]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
Input: raydium_i2c_ts - read device version in bootloader mode
authorsimba.hsu <simba.hsu@rad-ic.com>
Wed, 2 Jun 2021 04:38:38 +0000 (21:38 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 6 Sep 2021 02:42:43 +0000 (19:42 -0700)
Add support reading device ID when controller is in bootloader mode, which
may happen if firmware update has been interrupted.

Signed-off-by: simba.hsu <simba.hsu@rad-ic.com>
Link: https://lore.kernel.org/r/20210818063644.8654-1-simba.hsu@rad-ic.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/raydium_i2c_ts.c

index 4d2d22a8697732d9bb54cfb7abae3714fb5ebc5d..92c48d8e35a41efd29b679562646aa691e874788 100644 (file)
@@ -37,6 +37,7 @@
 #define RM_CMD_BOOT_READ       0x44            /* send wait bl data ready*/
 
 #define RM_BOOT_RDY            0xFF            /* bl data ready */
+#define RM_BOOT_CMD_READHWID   0x0E            /* read hwid */
 
 /* I2C main commands */
 #define RM_CMD_QUERY_BANK      0x2B
@@ -290,6 +291,44 @@ static int raydium_i2c_sw_reset(struct i2c_client *client)
        return 0;
 }
 
+static int raydium_i2c_query_ts_bootloader_info(struct raydium_data *ts)
+{
+       struct i2c_client *client = ts->client;
+       static const u8 get_hwid[] = { RM_BOOT_CMD_READHWID,
+                                      0x10, 0xc0, 0x01, 0x00, 0x04, 0x00 };
+       u8 rbuf[5] = { 0 };
+       u32 hw_ver;
+       int error;
+
+       error = raydium_i2c_send(client, RM_CMD_BOOT_WRT,
+                                get_hwid, sizeof(get_hwid));
+       if (error) {
+               dev_err(&client->dev, "WRT HWID command failed: %d\n", error);
+               return error;
+       }
+
+       error = raydium_i2c_send(client, RM_CMD_BOOT_ACK, rbuf, 1);
+       if (error) {
+               dev_err(&client->dev, "Ack HWID command failed: %d\n", error);
+               return error;
+       }
+
+       error = raydium_i2c_read(client, RM_CMD_BOOT_CHK, rbuf, sizeof(rbuf));
+       if (error) {
+               dev_err(&client->dev, "Read HWID command failed: %d (%4ph)\n",
+                       error, rbuf + 1);
+               hw_ver = 0xffffffffUL;
+       } else {
+               hw_ver = get_unaligned_be32(rbuf + 1);
+       }
+
+       ts->info.hw_ver = cpu_to_le32(hw_ver);
+       ts->info.main_ver = 0xff;
+       ts->info.sub_ver = 0xff;
+
+       return error;
+}
+
 static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 {
        struct i2c_client *client = ts->client;
@@ -388,13 +427,10 @@ static int raydium_i2c_initialize(struct raydium_data *ts)
        if (error)
                ts->boot_mode = RAYDIUM_TS_BLDR;
 
-       if (ts->boot_mode == RAYDIUM_TS_BLDR) {
-               ts->info.hw_ver = cpu_to_le32(0xffffffffUL);
-               ts->info.main_ver = 0xff;
-               ts->info.sub_ver = 0xff;
-       } else {
+       if (ts->boot_mode == RAYDIUM_TS_BLDR)
+               raydium_i2c_query_ts_bootloader_info(ts);
+       else
                raydium_i2c_query_ts_info(ts);
-       }
 
        return error;
 }
@@ -1218,7 +1254,7 @@ static SIMPLE_DEV_PM_OPS(raydium_i2c_pm_ops,
                         raydium_i2c_suspend, raydium_i2c_resume);
 
 static const struct i2c_device_id raydium_i2c_id[] = {
-       { "raydium_i2c" , 0 },
+       { "raydium_i2c", 0 },
        { "rm32380", 0 },
        { /* sentinel */ }
 };