diff mbox series

[3/3] Input: elan_i2c - Get the device information from PS/2 interface

Message ID 20191209111842.32390-1-dave.wang@emc.com.tw (mailing list archive)
State New, archived
Headers show
Series [1/3] Input: elan_i2c - Do no operation for elan_smbus_set_mode function | expand

Commit Message

Dave.Wang Dec. 9, 2019, 11:18 a.m. UTC
Get the device information from PS/2 interface for PS/2+SMBus
protocol such as product_id, fw_version, ic_type...etc.

Signed-off-by: Dave Wang <dave.wang@emc.com.tw>
---
 drivers/input/mouse/elan_i2c_smbus.c | 87 +++++++++++++++++-----------
 1 file changed, 54 insertions(+), 33 deletions(-)

Comments

Dmitry Torokhov July 21, 2020, 4:11 p.m. UTC | #1
Hi Dave,

On Mon, Dec 09, 2019 at 06:18:42AM -0500, Dave Wang wrote:
> Get the device information from PS/2 interface for PS/2+SMBus
> protocol such as product_id, fw_version, ic_type...etc.
> 
> Signed-off-by: Dave Wang <dave.wang@emc.com.tw>
> ---
>  drivers/input/mouse/elan_i2c_smbus.c | 87 +++++++++++++++++-----------
>  1 file changed, 54 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c
> index 9ffb1f834507..35919035ec89 100644
> --- a/drivers/input/mouse/elan_i2c_smbus.c
> +++ b/drivers/input/mouse/elan_i2c_smbus.c
> @@ -146,17 +146,22 @@ static int elan_smbus_get_version(struct i2c_client *client,
>  	int error;
>  	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
>  
> -	error = i2c_smbus_read_block_data(client,
> -					  iap ? ETP_SMBUS_IAP_VERSION_CMD :
> -						ETP_SMBUS_FW_VERSION_CMD,
> -					  val);
> -	if (error < 0) {
> -		dev_err(&client->dev, "failed to get %s version: %d\n",
> -			iap ? "IAP" : "FW", error);
> -		return error;
> +	if (device_property_read_u8(&client->dev,
> +				iap ? "elan,iap_version" : "elan,fw_version",
> +				version)) {

Should this be moved into core? Or we only plan on using this on SMbus?
What will happen after firmware update? How can userspace verify that
the firmware update completed successfully if we always return static
data? Can the device still be accessed via PS/2 while also using SMbus?

Thanks.
diff mbox series

Patch

diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c
index 9ffb1f834507..35919035ec89 100644
--- a/drivers/input/mouse/elan_i2c_smbus.c
+++ b/drivers/input/mouse/elan_i2c_smbus.c
@@ -146,17 +146,22 @@  static int elan_smbus_get_version(struct i2c_client *client,
 	int error;
 	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
-	error = i2c_smbus_read_block_data(client,
-					  iap ? ETP_SMBUS_IAP_VERSION_CMD :
-						ETP_SMBUS_FW_VERSION_CMD,
-					  val);
-	if (error < 0) {
-		dev_err(&client->dev, "failed to get %s version: %d\n",
-			iap ? "IAP" : "FW", error);
-		return error;
+	if (device_property_read_u8(&client->dev,
+				iap ? "elan,iap_version" : "elan,fw_version",
+				version)) {
+		error = i2c_smbus_read_block_data(client,
+				iap ? ETP_SMBUS_IAP_VERSION_CMD :
+				ETP_SMBUS_FW_VERSION_CMD,
+				val);
+		if (error < 0) {
+			dev_err(&client->dev, "failed to get %s version: %d\n",
+				iap ? "IAP" : "FW", error);
+			return error;
+		}
+
+		*version = val[2];
 	}
 
-	*version = val[2];
 	return 0;
 }
 
@@ -167,16 +172,21 @@  static int elan_smbus_get_sm_version(struct i2c_client *client,
 	int error;
 	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
-	error = i2c_smbus_read_block_data(client,
-					  ETP_SMBUS_SM_VERSION_CMD, val);
-	if (error < 0) {
-		dev_err(&client->dev, "failed to get SM version: %d\n", error);
-		return error;
+	if (device_property_read_u8(&client->dev, "elan,sm_version", version) ||
+	    device_property_read_u16(&client->dev, "elan,ic_type", ic_type)) {
+		error = i2c_smbus_read_block_data(client,
+						ETP_SMBUS_SM_VERSION_CMD, val);
+		if (error < 0) {
+			dev_err(&client->dev,
+				"failed to get SM version: %d\n", error);
+			return error;
+		}
+
+		*version = val[0];
+		*ic_type = val[1];
+		*clickpad = val[0] & 0x10;
 	}
 
-	*version = val[0];
-	*ic_type = val[1];
-	*clickpad = val[0] & 0x10;
 	return 0;
 }
 
@@ -185,14 +195,18 @@  static int elan_smbus_get_product_id(struct i2c_client *client, u16 *id)
 	int error;
 	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
-	error = i2c_smbus_read_block_data(client,
-					  ETP_SMBUS_UNIQUEID_CMD, val);
-	if (error < 0) {
-		dev_err(&client->dev, "failed to get product ID: %d\n", error);
-		return error;
+	if (device_property_read_u16(&client->dev, "elan,product_id", id)) {
+		error = i2c_smbus_read_block_data(client,
+						ETP_SMBUS_UNIQUEID_CMD, val);
+		if (error < 0) {
+			dev_err(&client->dev,
+				"failed to get product ID: %d\n", error);
+			return error;
+		}
+
+		*id = be16_to_cpup((__be16 *)val);
 	}
 
-	*id = be16_to_cpup((__be16 *)val);
 	return 0;
 }
 
@@ -202,17 +216,22 @@  static int elan_smbus_get_checksum(struct i2c_client *client,
 	int error;
 	u8 val[I2C_SMBUS_BLOCK_MAX] = {0};
 
-	error = i2c_smbus_read_block_data(client,
-					  iap ? ETP_SMBUS_FW_CHECKSUM_CMD :
-						ETP_SMBUS_IAP_CHECKSUM_CMD,
-					  val);
-	if (error < 0) {
-		dev_err(&client->dev, "failed to get %s checksum: %d\n",
-			iap ? "IAP" : "FW", error);
-		return error;
+	if (device_property_read_u16(&client->dev,
+				iap ? "elan,iap_checksum" : "elan,fw_checksum",
+				csum)) {
+		error = i2c_smbus_read_block_data(client,
+					iap ? ETP_SMBUS_IAP_CHECKSUM_CMD :
+						ETP_SMBUS_FW_CHECKSUM_CMD,
+						val);
+		if (error < 0) {
+			dev_err(&client->dev, "failed to get %s checksum: %d\n",
+				iap ? "IAP" : "FW", error);
+			return error;
+		}
+
+		*csum = be16_to_cpup((__be16 *)val);
 	}
 
-	*csum = be16_to_cpup((__be16 *)val);
 	return 0;
 }
 
@@ -496,7 +515,9 @@  static int elan_smbus_finish_fw_update(struct i2c_client *client,
 
 static int elan_smbus_get_pattern(struct i2c_client *client, u8 *pattern)
 {
-	*pattern = 0;
+	if (device_property_read_u8(&client->dev, "elan,pattern", pattern))
+		*pattern = 0;
+
 	return 0;
 }