Input: raydium_i2c_ts - read device version in bootloader mode

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>
This commit is contained in:
simba.hsu 2021-06-01 21:38:38 -07:00 committed by Dmitry Torokhov
parent 58ae4004b9
commit d5f9c43d41

View 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 */ }
};