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:
parent
58ae4004b9
commit
d5f9c43d41
|
@ -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 */ }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue