diff options
Diffstat (limited to 'drivers/input/touchscreen/raydium_i2c_ts.c')
| -rw-r--r-- | drivers/input/touchscreen/raydium_i2c_ts.c | 54 | 
1 files changed, 45 insertions, 9 deletions
| diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index 4d2d22a86977..3a4952935366 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -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;  } @@ -1082,11 +1118,11 @@ static int raydium_i2c_probe(struct i2c_client *client,  	if (error)  		return error; -	error = devm_add_action(&client->dev, raydium_i2c_power_off, ts); +	error = devm_add_action_or_reset(&client->dev, +					 raydium_i2c_power_off, ts);  	if (error) {  		dev_err(&client->dev,  			"failed to install power off action: %d\n", error); -		raydium_i2c_power_off(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 */ }  }; |