]> www.infradead.org Git - linux.git/commitdiff
Input: himax_hx83112b - implement MCU register reading
authorFelix Kaechele <felix@kaechele.ca>
Thu, 20 Jun 2024 14:50:04 +0000 (10:50 -0400)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 8 Jul 2024 23:22:50 +0000 (16:22 -0700)
Implement reading from the MCU in a more universal fashion. This allows
properly handling reads of more than 4 bytes using the AHB FIFO
implemented in the chip.

Signed-off-by: Felix Kaechele <felix@kaechele.ca>
Link: https://lore.kernel.org/r/20240620145019.156187-4-felix@kaechele.ca
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/himax_hx83112b.c

index d6c4a68eac231493151269e846141fa372822cbc..c9cc69bf242a5473fce835000656df233389d5a0 100644 (file)
 #define HIMAX_AHB_ADDR_BYTE_0                  0x00
 #define HIMAX_AHB_ADDR_RDATA_BYTE_0            0x08
 #define HIMAX_AHB_ADDR_ACCESS_DIRECTION                0x0c
+#define HIMAX_AHB_ADDR_INCR4                   0x0d
+#define HIMAX_AHB_ADDR_CONTI                   0x13
 #define HIMAX_AHB_ADDR_EVENT_STACK             0x30
 
 #define HIMAX_AHB_CMD_ACCESS_DIRECTION_READ    0x00
+#define HIMAX_AHB_CMD_INCR4                    0x10
+#define HIMAX_AHB_CMD_CONTI                    0x31
 
 #define HIMAX_REG_ADDR_ICID                    0x900000d0
 
@@ -65,10 +69,34 @@ static const struct regmap_config himax_regmap_config = {
        .val_format_endian = REGMAP_ENDIAN_LITTLE,
 };
 
-static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst)
+static int himax_bus_enable_burst(struct himax_ts_data *ts)
 {
        int error;
 
+       error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_CONTI,
+                            HIMAX_AHB_CMD_CONTI);
+       if (error)
+               return error;
+
+       error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_INCR4,
+                            HIMAX_AHB_CMD_INCR4);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static int himax_bus_read(struct himax_ts_data *ts, u32 address, void *dst,
+                         size_t length)
+{
+       int error;
+
+       if (length > 4) {
+               error = himax_bus_enable_burst(ts);
+               if (error)
+                       return error;
+       }
+
        error = regmap_write(ts->regmap, HIMAX_AHB_ADDR_BYTE_0, address);
        if (error)
                return error;
@@ -78,7 +106,23 @@ static int himax_read_config(struct himax_ts_data *ts, u32 address, u32 *dst)
        if (error)
                return error;
 
-       error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0, dst);
+       if (length > 4)
+               error = regmap_noinc_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0,
+                                         dst, length);
+       else
+               error = regmap_read(ts->regmap, HIMAX_AHB_ADDR_RDATA_BYTE_0,
+                                   dst);
+       if (error)
+               return error;
+
+       return 0;
+}
+
+static int himax_read_mcu(struct himax_ts_data *ts, u32 address, u32 *dst)
+{
+       int error;
+
+       error = himax_bus_read(ts, address, dst, sizeof(dst));
        if (error)
                return error;
 
@@ -104,7 +148,7 @@ static int himax_read_product_id(struct himax_ts_data *ts, u32 *product_id)
 {
        int error;
 
-       error = himax_read_config(ts, HIMAX_REG_ADDR_ICID, product_id);
+       error = himax_read_mcu(ts, HIMAX_REG_ADDR_ICID, product_id);
        if (error)
                return error;