summaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/iqs5xx.c
diff options
context:
space:
mode:
authorJeff LaBundy <jeff@labundy.com>2021-03-23 04:15:32 +0100
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2021-03-25 19:14:10 +0100
commit9d41359caca7cdc6d3011ba4e485e89d40505e81 (patch)
tree64fe4318653f96a0706e413f789ec6b9b4ab79ff /drivers/input/touchscreen/iqs5xx.c
parentInput: Add support for Azoteq IQS626A (diff)
downloadlinux-9d41359caca7cdc6d3011ba4e485e89d40505e81.tar.xz
linux-9d41359caca7cdc6d3011ba4e485e89d40505e81.zip
Input: iqs5xx - make reset GPIO optional
The device's hardware reset pin is only required if the platform must be able to update the device's firmware. As such, demote the reset GPIO to optional in support of devices that ship with pre-programmed firmware and don't route the reset pin back to the SoC. In that case, the 'fw_file' attribute is hidden because there is no way to open the bootloader. The logic is extended to the case in which the device does not advertise bootloader support in the first place. Last but not least, remove the hardware reset performed at probe because there is no reason to reset the device manually. A power on reset function already ensures a clean reset at start-up. Signed-off-by: Jeff LaBundy <jeff@labundy.com> Link: https://lore.kernel.org/r/20210323021006.367-1-jeff@labundy.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input/touchscreen/iqs5xx.c')
-rw-r--r--drivers/input/touchscreen/iqs5xx.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/input/touchscreen/iqs5xx.c b/drivers/input/touchscreen/iqs5xx.c
index a990c176abf7..b3fa71213d60 100644
--- a/drivers/input/touchscreen/iqs5xx.c
+++ b/drivers/input/touchscreen/iqs5xx.c
@@ -835,9 +835,6 @@ static int iqs5xx_fw_file_write(struct i2c_client *client, const char *fw_file)
int error, error_init = 0;
u8 *pmap;
- if (iqs5xx->dev_id_info.bl_status == IQS5XX_BL_STATUS_NONE)
- return -EPERM;
-
pmap = kzalloc(IQS5XX_PMAP_LEN, GFP_KERNEL);
if (!pmap)
return -ENOMEM;
@@ -963,7 +960,22 @@ static struct attribute *iqs5xx_attrs[] = {
NULL,
};
+static umode_t iqs5xx_attr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int i)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev);
+
+ if (attr == &dev_attr_fw_file.attr &&
+ (iqs5xx->dev_id_info.bl_status == IQS5XX_BL_STATUS_NONE ||
+ !iqs5xx->reset_gpio))
+ return 0;
+
+ return attr->mode;
+}
+
static const struct attribute_group iqs5xx_attr_group = {
+ .is_visible = iqs5xx_attr_is_visible,
.attrs = iqs5xx_attrs,
};
@@ -1020,8 +1032,8 @@ static int iqs5xx_probe(struct i2c_client *client,
i2c_set_clientdata(client, iqs5xx);
iqs5xx->client = client;
- iqs5xx->reset_gpio = devm_gpiod_get(&client->dev,
- "reset", GPIOD_OUT_LOW);
+ iqs5xx->reset_gpio = devm_gpiod_get_optional(&client->dev,
+ "reset", GPIOD_OUT_LOW);
if (IS_ERR(iqs5xx->reset_gpio)) {
error = PTR_ERR(iqs5xx->reset_gpio);
dev_err(&client->dev, "Failed to request GPIO: %d\n", error);
@@ -1030,9 +1042,6 @@ static int iqs5xx_probe(struct i2c_client *client,
mutex_init(&iqs5xx->lock);
- iqs5xx_reset(client);
- usleep_range(10000, 10100);
-
error = iqs5xx_dev_init(client);
if (error)
return error;