Re: [PATCH v1 07/10] Input: atmel_mxt_ts - zero terminate config firmware file

2018-07-24 Thread Nick Dyer
On Mon, Jul 23, 2018 at 03:35:34PM -0700, Dmitry Torokhov wrote:
> On Fri, Jul 20, 2018 at 10:51:19PM +0100, Nick Dyer wrote:
> > From: Nick Dyer 
> > 
> > We use sscanf to parse the configuration file, so it's necessary to zero
> > terminate the configuration otherwise a truncated file can cause the
> > parser to run off into uninitialised memory.
> > 
> > Signed-off-by: Nick Dyer 
> > ---
> >  drivers/input/touchscreen/atmel_mxt_ts.c | 36 +---
> >  1 file changed, 26 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> > b/drivers/input/touchscreen/atmel_mxt_ts.c
> > index 0ce126e918f1..2d1fddafb7f9 100644
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -279,7 +279,7 @@ enum mxt_suspend_mode {
> >  
> >  /* Config update context */
> >  struct mxt_cfg {
> > -   const u8 *raw;
> > +   u8 *raw;
> > size_t raw_size;
> > off_t raw_pos;
> >  
> > @@ -1451,14 +1451,21 @@ static int mxt_update_cfg(struct mxt_data *data, 
> > const struct firmware *fw)
> > u32 info_crc, config_crc, calculated_crc;
> > u16 crc_start = 0;
> >  
> > -   cfg.raw = fw->data;
> > +   /* Make zero terminated copy of the OBP_RAW file */
> > +   cfg.raw = kzalloc(fw->size + 1, GFP_KERNEL);
> 
> kmemdup_nul()? I guess config it not that big to be concerned with
> kmalloc() vs vmalloc() and allocation failures...

Yes, that looks like it should work. There's a limit on the size of the
data due to the I2C address space, so we should be fine.

Nick


Re: [PATCH v1 07/10] Input: atmel_mxt_ts - zero terminate config firmware file

2018-07-24 Thread Nick Dyer
On Mon, Jul 23, 2018 at 03:35:34PM -0700, Dmitry Torokhov wrote:
> On Fri, Jul 20, 2018 at 10:51:19PM +0100, Nick Dyer wrote:
> > From: Nick Dyer 
> > 
> > We use sscanf to parse the configuration file, so it's necessary to zero
> > terminate the configuration otherwise a truncated file can cause the
> > parser to run off into uninitialised memory.
> > 
> > Signed-off-by: Nick Dyer 
> > ---
> >  drivers/input/touchscreen/atmel_mxt_ts.c | 36 +---
> >  1 file changed, 26 insertions(+), 10 deletions(-)
> > 
> > diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> > b/drivers/input/touchscreen/atmel_mxt_ts.c
> > index 0ce126e918f1..2d1fddafb7f9 100644
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -279,7 +279,7 @@ enum mxt_suspend_mode {
> >  
> >  /* Config update context */
> >  struct mxt_cfg {
> > -   const u8 *raw;
> > +   u8 *raw;
> > size_t raw_size;
> > off_t raw_pos;
> >  
> > @@ -1451,14 +1451,21 @@ static int mxt_update_cfg(struct mxt_data *data, 
> > const struct firmware *fw)
> > u32 info_crc, config_crc, calculated_crc;
> > u16 crc_start = 0;
> >  
> > -   cfg.raw = fw->data;
> > +   /* Make zero terminated copy of the OBP_RAW file */
> > +   cfg.raw = kzalloc(fw->size + 1, GFP_KERNEL);
> 
> kmemdup_nul()? I guess config it not that big to be concerned with
> kmalloc() vs vmalloc() and allocation failures...

Yes, that looks like it should work. There's a limit on the size of the
data due to the I2C address space, so we should be fine.

Nick


[PATCH v1 08/10] Input: atmel_mxt_ts - don't report zero pressure from T9

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

If T9.CTRL DISAMP is set, then pressure is reported as zero. This means
some app layers (eg tslib) will ignore the contact.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2d1fddafb7f9..d7023d261458 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -843,6 +843,10 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
mxt_input_sync(data);
}
 
+   /* if active, pressure must be non-zero */
+   if (!amplitude)
+   amplitude = MXT_PRESSURE_DEFAULT;
+
/* Touch active */
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
input_report_abs(input_dev, ABS_MT_POSITION_X, x);
-- 
2.17.1



[PATCH v1 04/10] Input: atmel_mxt_ts - remove unnecessary debug on ENOMEM

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index dcafb812ee7e..92661aa910ae 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1520,10 +1520,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
MXT_INFO_CHECKSUM_SIZE;
config_mem_size = data->mem_size - cfg_start_ofs;
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
-   if (!config_mem) {
-   dev_err(dev, "Failed to allocate memory\n");
+   if (!config_mem)
return -ENOMEM;
-   }
 
ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs,
  config_mem, config_mem_size);
@@ -1982,10 +1980,8 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
 
/* Register input device */
input_dev = input_allocate_device();
-   if (!input_dev) {
-   dev_err(dev, "Failed to allocate memory\n");
+   if (!input_dev)
return -ENOMEM;
-   }
 
input_dev->name = "Atmel maXTouch Touchscreen";
input_dev->phys = data->phys;
-- 
2.17.1



[PATCH v1 09/10] Input: atmel_mxt_ts - tool type is ignored when slot is closed

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

input_mt_report_slot_state() ignores the tool when the slot is closed.
Remove the tool type from these function calls, which has caused a bit of
confusion.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index d7023d261458..c31af790ef84 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -838,8 +838,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
 * have happened.
 */
if (status & MXT_T9_RELEASE) {
-   input_mt_report_slot_state(input_dev,
-  MT_TOOL_FINGER, 0);
+   input_mt_report_slot_state(input_dev, 0, 0);
mxt_input_sync(data);
}
 
@@ -855,7 +854,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
} else {
/* Touch no longer active, close out slot */
-   input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+   input_mt_report_slot_state(input_dev, 0, 0);
}
 
data->update_input = true;
-- 
2.17.1



[PATCH v1 07/10] Input: atmel_mxt_ts - zero terminate config firmware file

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

We use sscanf to parse the configuration file, so it's necessary to zero
terminate the configuration otherwise a truncated file can cause the
parser to run off into uninitialised memory.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 36 +---
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0ce126e918f1..2d1fddafb7f9 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -279,7 +279,7 @@ enum mxt_suspend_mode {
 
 /* Config update context */
 struct mxt_cfg {
-   const u8 *raw;
+   u8 *raw;
size_t raw_size;
off_t raw_pos;
 
@@ -1451,14 +1451,21 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
u32 info_crc, config_crc, calculated_crc;
u16 crc_start = 0;
 
-   cfg.raw = fw->data;
+   /* Make zero terminated copy of the OBP_RAW file */
+   cfg.raw = kzalloc(fw->size + 1, GFP_KERNEL);
+   if (!cfg.raw)
+   return -ENOMEM;
+
+   memcpy(cfg.raw, fw->data, fw->size);
+   cfg.raw[fw->size] = '\0';
cfg.raw_size = fw->size;
 
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
 
if (strncmp(cfg.raw, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
dev_err(dev, "Unrecognised config file\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
cfg.raw_pos = strlen(MXT_CFG_MAGIC);
@@ -1470,7 +1477,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
 );
if (ret != 1) {
dev_err(dev, "Bad format\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
cfg.raw_pos += offset;
@@ -1478,26 +1486,30 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
 
if (cfg.info.family_id != data->info->family_id) {
dev_err(dev, "Family ID mismatch!\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
if (cfg.info.variant_id != data->info->variant_id) {
dev_err(dev, "Variant ID mismatch!\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
/* Read CRCs */
ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", _crc, );
if (ret != 1) {
dev_err(dev, "Bad format: failed to parse Info CRC\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
cfg.raw_pos += offset;
 
ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", _crc, );
if (ret != 1) {
dev_err(dev, "Bad format: failed to parse Config CRC\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
cfg.raw_pos += offset;
 
@@ -1530,8 +1542,10 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
MXT_INFO_CHECKSUM_SIZE;
cfg.mem_size = data->mem_size - cfg.start_ofs;
cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL);
-   if (!cfg.mem)
-   return -ENOMEM;
+   if (!cfg.mem) {
+   ret = -ENOMEM;
+   goto release_raw;
+   }
 
ret = mxt_prepare_cfg_mem(data, );
if (ret)
@@ -1570,6 +1584,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
/* T7 config may have changed */
mxt_init_t7_power_cfg(data);
 
+release_raw:
+   kfree(cfg.raw);
 release_mem:
kfree(cfg.mem);
return ret;
-- 
2.17.1



[PATCH v1 10/10] Input: atmel_mxt_ts - move completion to after config crc is updated

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index c31af790ef84..9f296a66c94e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -728,13 +728,13 @@ static void mxt_proc_t6_messages(struct mxt_data *data, 
u8 *msg)
u8 status = msg[1];
u32 crc = msg[2] | (msg[3] << 8) | (msg[4] << 16);
 
-   complete(>crc_completion);
-
if (crc != data->config_crc) {
data->config_crc = crc;
dev_dbg(dev, "T6 Config Checksum: 0x%06X\n", crc);
}
 
+   complete(>crc_completion);
+
/* Detect reset */
if (status & MXT_T6_STATUS_RESET)
complete(>reset_completion);
-- 
2.17.1



[PATCH v1 08/10] Input: atmel_mxt_ts - don't report zero pressure from T9

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

If T9.CTRL DISAMP is set, then pressure is reported as zero. This means
some app layers (eg tslib) will ignore the contact.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 2d1fddafb7f9..d7023d261458 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -843,6 +843,10 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
mxt_input_sync(data);
}
 
+   /* if active, pressure must be non-zero */
+   if (!amplitude)
+   amplitude = MXT_PRESSURE_DEFAULT;
+
/* Touch active */
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 1);
input_report_abs(input_dev, ABS_MT_POSITION_X, x);
-- 
2.17.1



[PATCH v1 04/10] Input: atmel_mxt_ts - remove unnecessary debug on ENOMEM

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index dcafb812ee7e..92661aa910ae 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1520,10 +1520,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
MXT_INFO_CHECKSUM_SIZE;
config_mem_size = data->mem_size - cfg_start_ofs;
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
-   if (!config_mem) {
-   dev_err(dev, "Failed to allocate memory\n");
+   if (!config_mem)
return -ENOMEM;
-   }
 
ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs,
  config_mem, config_mem_size);
@@ -1982,10 +1980,8 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
 
/* Register input device */
input_dev = input_allocate_device();
-   if (!input_dev) {
-   dev_err(dev, "Failed to allocate memory\n");
+   if (!input_dev)
return -ENOMEM;
-   }
 
input_dev->name = "Atmel maXTouch Touchscreen";
input_dev->phys = data->phys;
-- 
2.17.1



[PATCH v1 09/10] Input: atmel_mxt_ts - tool type is ignored when slot is closed

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

input_mt_report_slot_state() ignores the tool when the slot is closed.
Remove the tool type from these function calls, which has caused a bit of
confusion.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index d7023d261458..c31af790ef84 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -838,8 +838,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
 * have happened.
 */
if (status & MXT_T9_RELEASE) {
-   input_mt_report_slot_state(input_dev,
-  MT_TOOL_FINGER, 0);
+   input_mt_report_slot_state(input_dev, 0, 0);
mxt_input_sync(data);
}
 
@@ -855,7 +854,7 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 
*message)
input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, area);
} else {
/* Touch no longer active, close out slot */
-   input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
+   input_mt_report_slot_state(input_dev, 0, 0);
}
 
data->update_input = true;
-- 
2.17.1



[PATCH v1 07/10] Input: atmel_mxt_ts - zero terminate config firmware file

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

We use sscanf to parse the configuration file, so it's necessary to zero
terminate the configuration otherwise a truncated file can cause the
parser to run off into uninitialised memory.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 36 +---
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0ce126e918f1..2d1fddafb7f9 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -279,7 +279,7 @@ enum mxt_suspend_mode {
 
 /* Config update context */
 struct mxt_cfg {
-   const u8 *raw;
+   u8 *raw;
size_t raw_size;
off_t raw_pos;
 
@@ -1451,14 +1451,21 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
u32 info_crc, config_crc, calculated_crc;
u16 crc_start = 0;
 
-   cfg.raw = fw->data;
+   /* Make zero terminated copy of the OBP_RAW file */
+   cfg.raw = kzalloc(fw->size + 1, GFP_KERNEL);
+   if (!cfg.raw)
+   return -ENOMEM;
+
+   memcpy(cfg.raw, fw->data, fw->size);
+   cfg.raw[fw->size] = '\0';
cfg.raw_size = fw->size;
 
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
 
if (strncmp(cfg.raw, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
dev_err(dev, "Unrecognised config file\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
cfg.raw_pos = strlen(MXT_CFG_MAGIC);
@@ -1470,7 +1477,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
 );
if (ret != 1) {
dev_err(dev, "Bad format\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
cfg.raw_pos += offset;
@@ -1478,26 +1486,30 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
 
if (cfg.info.family_id != data->info->family_id) {
dev_err(dev, "Family ID mismatch!\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
if (cfg.info.variant_id != data->info->variant_id) {
dev_err(dev, "Variant ID mismatch!\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
 
/* Read CRCs */
ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", _crc, );
if (ret != 1) {
dev_err(dev, "Bad format: failed to parse Info CRC\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
cfg.raw_pos += offset;
 
ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", _crc, );
if (ret != 1) {
dev_err(dev, "Bad format: failed to parse Config CRC\n");
-   return -EINVAL;
+   ret = -EINVAL;
+   goto release_raw;
}
cfg.raw_pos += offset;
 
@@ -1530,8 +1542,10 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
MXT_INFO_CHECKSUM_SIZE;
cfg.mem_size = data->mem_size - cfg.start_ofs;
cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL);
-   if (!cfg.mem)
-   return -ENOMEM;
+   if (!cfg.mem) {
+   ret = -ENOMEM;
+   goto release_raw;
+   }
 
ret = mxt_prepare_cfg_mem(data, );
if (ret)
@@ -1570,6 +1584,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *fw)
/* T7 config may have changed */
mxt_init_t7_power_cfg(data);
 
+release_raw:
+   kfree(cfg.raw);
 release_mem:
kfree(cfg.mem);
return ret;
-- 
2.17.1



[PATCH v1 10/10] Input: atmel_mxt_ts - move completion to after config crc is updated

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index c31af790ef84..9f296a66c94e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -728,13 +728,13 @@ static void mxt_proc_t6_messages(struct mxt_data *data, 
u8 *msg)
u8 status = msg[1];
u32 crc = msg[2] | (msg[3] << 8) | (msg[4] << 16);
 
-   complete(>crc_completion);
-
if (crc != data->config_crc) {
data->config_crc = crc;
dev_dbg(dev, "T6 Config Checksum: 0x%06X\n", crc);
}
 
+   complete(>crc_completion);
+
/* Detect reset */
if (status & MXT_T6_STATUS_RESET)
complete(>reset_completion);
-- 
2.17.1



[PATCH v1 01/10] Input: atmel_mxt_ts - only use first T9 instance

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

The driver only registers one input device, which uses the screen
parameters from the first T9 instance. The first T63 instance also uses
those parameters.

It is incorrect to send input reports from the second instances of these
objects if they are enabled: the input scaling will be wrong and the
positions will be mashed together.

This also causes problems on Android if the number of slots exceeds 32.

In the future, this could be handled by looking for enabled touch object
instances and creating an input device for each one.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 54fe190fd4bc..48c5ccab00a0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1658,10 +1658,11 @@ static int mxt_parse_object_table(struct mxt_data *data,
break;
case MXT_TOUCH_MULTI_T9:
data->multitouch = MXT_TOUCH_MULTI_T9;
+   /* Only handle messages from first T9 instance */
data->T9_reportid_min = min_id;
-   data->T9_reportid_max = max_id;
-   data->num_touchids = object->num_report_ids
-   * mxt_obj_instances(object);
+   data->T9_reportid_max = min_id +
+   object->num_report_ids - 1;
+   data->num_touchids = object->num_report_ids;
break;
case MXT_SPT_MESSAGECOUNT_T44:
data->T44_address = object->start_address;
-- 
2.17.1



[PATCH v1 02/10] Input: atmel_mxt_ts - use BIT() macro everywhere

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 36 
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 48c5ccab00a0..9555947a2d46 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -88,12 +88,12 @@
 #define MXT_COMMAND_DIAGNOSTIC 5
 
 /* Define for T6 status byte */
-#define MXT_T6_STATUS_RESET(1 << 7)
-#define MXT_T6_STATUS_OFL  (1 << 6)
-#define MXT_T6_STATUS_SIGERR   (1 << 5)
-#define MXT_T6_STATUS_CAL  (1 << 4)
-#define MXT_T6_STATUS_CFGERR   (1 << 3)
-#define MXT_T6_STATUS_COMSERR  (1 << 2)
+#define MXT_T6_STATUS_RESETBIT(7)
+#define MXT_T6_STATUS_OFL  BIT(6)
+#define MXT_T6_STATUS_SIGERR   BIT(5)
+#define MXT_T6_STATUS_CAL  BIT(4)
+#define MXT_T6_STATUS_CFGERR   BIT(3)
+#define MXT_T6_STATUS_COMSERR  BIT(2)
 
 /* MXT_GEN_POWER_T7 field */
 struct t7_config {
@@ -112,14 +112,14 @@ struct t7_config {
 #define MXT_T9_RANGE   18
 
 /* MXT_TOUCH_MULTI_T9 status */
-#define MXT_T9_UNGRIP  (1 << 0)
-#define MXT_T9_SUPPRESS(1 << 1)
-#define MXT_T9_AMP (1 << 2)
-#define MXT_T9_VECTOR  (1 << 3)
-#define MXT_T9_MOVE(1 << 4)
-#define MXT_T9_RELEASE (1 << 5)
-#define MXT_T9_PRESS   (1 << 6)
-#define MXT_T9_DETECT  (1 << 7)
+#define MXT_T9_UNGRIP  BIT(0)
+#define MXT_T9_SUPPRESSBIT(1)
+#define MXT_T9_AMP BIT(2)
+#define MXT_T9_VECTOR  BIT(3)
+#define MXT_T9_MOVEBIT(4)
+#define MXT_T9_RELEASE BIT(5)
+#define MXT_T9_PRESS   BIT(6)
+#define MXT_T9_DETECT  BIT(7)
 
 struct t9_range {
__le16 x;
@@ -127,9 +127,9 @@ struct t9_range {
 } __packed;
 
 /* MXT_TOUCH_MULTI_T9 orient */
-#define MXT_T9_ORIENT_SWITCH   (1 << 0)
-#define MXT_T9_ORIENT_INVERTX  (1 << 1)
-#define MXT_T9_ORIENT_INVERTY  (1 << 2)
+#define MXT_T9_ORIENT_SWITCH   BIT(0)
+#define MXT_T9_ORIENT_INVERTX  BIT(1)
+#define MXT_T9_ORIENT_INVERTY  BIT(2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -214,7 +214,7 @@ enum t100_type {
 #define MXT_FRAME_CRC_PASS 0x04
 #define MXT_APP_CRC_FAIL   0x40/* valid 7 8 bit only */
 #define MXT_BOOT_STATUS_MASK   0x3f
-#define MXT_BOOT_EXTENDED_ID   (1 << 5)
+#define MXT_BOOT_EXTENDED_ID   BIT(5)
 #define MXT_BOOT_ID_MASK   0x1f
 
 /* Touchscreen absolute values */
-- 
2.17.1



[PATCH v1 06/10] Input: atmel_mxt_ts - refactor config update code to add context struct

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 108 ---
 1 file changed, 56 insertions(+), 52 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 560d4997ef8c..0ce126e918f1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -277,6 +277,19 @@ enum mxt_suspend_mode {
MXT_SUSPEND_T9_CTRL = 1,
 };
 
+/* Config update context */
+struct mxt_cfg {
+   const u8 *raw;
+   size_t raw_size;
+   off_t raw_pos;
+
+   u8 *mem;
+   size_t mem_size;
+   int start_ofs;
+
+   struct mxt_info info;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -1282,12 +1295,7 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, 
off_t end_off)
return crc;
 }
 
-static int mxt_prepare_cfg_mem(struct mxt_data *data,
-  const struct firmware *cfg,
-  unsigned int data_pos,
-  unsigned int cfg_start_ofs,
-  u8 *config_mem,
-  size_t config_mem_size)
+static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
 {
struct device *dev = >client->dev;
struct mxt_object *object;
@@ -1298,9 +1306,9 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
u16 reg;
u8 val;
 
-   while (data_pos < cfg->size) {
+   while (cfg->raw_pos < cfg->raw_size) {
/* Read type, instance, length */
-   ret = sscanf(cfg->data + data_pos, "%x %x %x%n",
+   ret = sscanf(cfg->raw + cfg->raw_pos, "%x %x %x%n",
 , , , );
if (ret == 0) {
/* EOF */
@@ -1309,20 +1317,20 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
dev_err(dev, "Bad format: failed to parse object\n");
return -EINVAL;
}
-   data_pos += offset;
+   cfg->raw_pos += offset;
 
object = mxt_get_object(data, type);
if (!object) {
/* Skip object */
for (i = 0; i < size; i++) {
-   ret = sscanf(cfg->data + data_pos, "%hhx%n",
+   ret = sscanf(cfg->raw + cfg->raw_pos, "%hhx%n",
 , );
if (ret != 1) {
dev_err(dev, "Bad format in T%d at 
%d\n",
type, i);
return -EINVAL;
}
-   data_pos += offset;
+   cfg->raw_pos += offset;
}
continue;
}
@@ -1357,7 +1365,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
reg = object->start_address + mxt_obj_size(object) * instance;
 
for (i = 0; i < size; i++) {
-   ret = sscanf(cfg->data + data_pos, "%hhx%n",
+   ret = sscanf(cfg->raw + cfg->raw_pos, "%hhx%n",
 ,
 );
if (ret != 1) {
@@ -1365,15 +1373,15 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
type, i);
return -EINVAL;
}
-   data_pos += offset;
+   cfg->raw_pos += offset;
 
if (i > mxt_obj_size(object))
continue;
 
-   byte_offset = reg + i - cfg_start_ofs;
+   byte_offset = reg + i - cfg->start_ofs;
 
-   if (byte_offset >= 0 && byte_offset < config_mem_size) {
-   *(config_mem + byte_offset) = val;
+   if (byte_offset >= 0 && byte_offset < cfg->mem_size) {
+   *(cfg->mem + byte_offset) = val;
} else {
dev_err(dev, "Bad object: reg:%d, T%d, 
ofs=%d\n",
reg, object->type, byte_offset);
@@ -1385,22 +1393,21 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
return 0;
 }
 
-static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start,
- u8 *config_mem, size_t config_mem_size)
+static int mxt_upload_cfg

[PATCH v1 03/10] Input: atmel_mxt_ts - remove duplicate setup of ABS_MT_PRESSURE

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 9555947a2d46..dcafb812ee7e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2055,12 +2055,6 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
 0, 255, 0, 0);
}
 
-   if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
-   data->t100_aux_ampl) {
-   input_set_abs_params(input_dev, ABS_MT_PRESSURE,
-0, 255, 0, 0);
-   }
-
if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
data->t100_aux_vect) {
input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
-- 
2.17.1



[PATCH v1 06/10] Input: atmel_mxt_ts - refactor config update code to add context struct

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 108 ---
 1 file changed, 56 insertions(+), 52 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 560d4997ef8c..0ce126e918f1 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -277,6 +277,19 @@ enum mxt_suspend_mode {
MXT_SUSPEND_T9_CTRL = 1,
 };
 
+/* Config update context */
+struct mxt_cfg {
+   const u8 *raw;
+   size_t raw_size;
+   off_t raw_pos;
+
+   u8 *mem;
+   size_t mem_size;
+   int start_ofs;
+
+   struct mxt_info info;
+};
+
 /* Each client has this additional data */
 struct mxt_data {
struct i2c_client *client;
@@ -1282,12 +1295,7 @@ static u32 mxt_calculate_crc(u8 *base, off_t start_off, 
off_t end_off)
return crc;
 }
 
-static int mxt_prepare_cfg_mem(struct mxt_data *data,
-  const struct firmware *cfg,
-  unsigned int data_pos,
-  unsigned int cfg_start_ofs,
-  u8 *config_mem,
-  size_t config_mem_size)
+static int mxt_prepare_cfg_mem(struct mxt_data *data, struct mxt_cfg *cfg)
 {
struct device *dev = >client->dev;
struct mxt_object *object;
@@ -1298,9 +1306,9 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
u16 reg;
u8 val;
 
-   while (data_pos < cfg->size) {
+   while (cfg->raw_pos < cfg->raw_size) {
/* Read type, instance, length */
-   ret = sscanf(cfg->data + data_pos, "%x %x %x%n",
+   ret = sscanf(cfg->raw + cfg->raw_pos, "%x %x %x%n",
 , , , );
if (ret == 0) {
/* EOF */
@@ -1309,20 +1317,20 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
dev_err(dev, "Bad format: failed to parse object\n");
return -EINVAL;
}
-   data_pos += offset;
+   cfg->raw_pos += offset;
 
object = mxt_get_object(data, type);
if (!object) {
/* Skip object */
for (i = 0; i < size; i++) {
-   ret = sscanf(cfg->data + data_pos, "%hhx%n",
+   ret = sscanf(cfg->raw + cfg->raw_pos, "%hhx%n",
 , );
if (ret != 1) {
dev_err(dev, "Bad format in T%d at 
%d\n",
type, i);
return -EINVAL;
}
-   data_pos += offset;
+   cfg->raw_pos += offset;
}
continue;
}
@@ -1357,7 +1365,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
reg = object->start_address + mxt_obj_size(object) * instance;
 
for (i = 0; i < size; i++) {
-   ret = sscanf(cfg->data + data_pos, "%hhx%n",
+   ret = sscanf(cfg->raw + cfg->raw_pos, "%hhx%n",
 ,
 );
if (ret != 1) {
@@ -1365,15 +1373,15 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
type, i);
return -EINVAL;
}
-   data_pos += offset;
+   cfg->raw_pos += offset;
 
if (i > mxt_obj_size(object))
continue;
 
-   byte_offset = reg + i - cfg_start_ofs;
+   byte_offset = reg + i - cfg->start_ofs;
 
-   if (byte_offset >= 0 && byte_offset < config_mem_size) {
-   *(config_mem + byte_offset) = val;
+   if (byte_offset >= 0 && byte_offset < cfg->mem_size) {
+   *(cfg->mem + byte_offset) = val;
} else {
dev_err(dev, "Bad object: reg:%d, T%d, 
ofs=%d\n",
reg, object->type, byte_offset);
@@ -1385,22 +1393,21 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
return 0;
 }
 
-static int mxt_upload_cfg_mem(struct mxt_data *data, unsigned int cfg_start,
- u8 *config_mem, size_t config_mem_size)
+static int mxt_upload_cfg

[PATCH v1 03/10] Input: atmel_mxt_ts - remove duplicate setup of ABS_MT_PRESSURE

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 6 --
 1 file changed, 6 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 9555947a2d46..dcafb812ee7e 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -2055,12 +2055,6 @@ static int mxt_initialize_input_device(struct mxt_data 
*data)
 0, 255, 0, 0);
}
 
-   if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
-   data->t100_aux_ampl) {
-   input_set_abs_params(input_dev, ABS_MT_PRESSURE,
-0, 255, 0, 0);
-   }
-
if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 &&
data->t100_aux_vect) {
input_set_abs_params(input_dev, ABS_MT_ORIENTATION,
-- 
2.17.1



[PATCH v1 01/10] Input: atmel_mxt_ts - only use first T9 instance

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

The driver only registers one input device, which uses the screen
parameters from the first T9 instance. The first T63 instance also uses
those parameters.

It is incorrect to send input reports from the second instances of these
objects if they are enabled: the input scaling will be wrong and the
positions will be mashed together.

This also causes problems on Android if the number of slots exceeds 32.

In the future, this could be handled by looking for enabled touch object
instances and creating an input device for each one.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
Acked-by: Yufeng Shen 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 54fe190fd4bc..48c5ccab00a0 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -1658,10 +1658,11 @@ static int mxt_parse_object_table(struct mxt_data *data,
break;
case MXT_TOUCH_MULTI_T9:
data->multitouch = MXT_TOUCH_MULTI_T9;
+   /* Only handle messages from first T9 instance */
data->T9_reportid_min = min_id;
-   data->T9_reportid_max = max_id;
-   data->num_touchids = object->num_report_ids
-   * mxt_obj_instances(object);
+   data->T9_reportid_max = min_id +
+   object->num_report_ids - 1;
+   data->num_touchids = object->num_report_ids;
break;
case MXT_SPT_MESSAGECOUNT_T44:
data->T44_address = object->start_address;
-- 
2.17.1



[PATCH v1 02/10] Input: atmel_mxt_ts - use BIT() macro everywhere

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 36 
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 48c5ccab00a0..9555947a2d46 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -88,12 +88,12 @@
 #define MXT_COMMAND_DIAGNOSTIC 5
 
 /* Define for T6 status byte */
-#define MXT_T6_STATUS_RESET(1 << 7)
-#define MXT_T6_STATUS_OFL  (1 << 6)
-#define MXT_T6_STATUS_SIGERR   (1 << 5)
-#define MXT_T6_STATUS_CAL  (1 << 4)
-#define MXT_T6_STATUS_CFGERR   (1 << 3)
-#define MXT_T6_STATUS_COMSERR  (1 << 2)
+#define MXT_T6_STATUS_RESETBIT(7)
+#define MXT_T6_STATUS_OFL  BIT(6)
+#define MXT_T6_STATUS_SIGERR   BIT(5)
+#define MXT_T6_STATUS_CAL  BIT(4)
+#define MXT_T6_STATUS_CFGERR   BIT(3)
+#define MXT_T6_STATUS_COMSERR  BIT(2)
 
 /* MXT_GEN_POWER_T7 field */
 struct t7_config {
@@ -112,14 +112,14 @@ struct t7_config {
 #define MXT_T9_RANGE   18
 
 /* MXT_TOUCH_MULTI_T9 status */
-#define MXT_T9_UNGRIP  (1 << 0)
-#define MXT_T9_SUPPRESS(1 << 1)
-#define MXT_T9_AMP (1 << 2)
-#define MXT_T9_VECTOR  (1 << 3)
-#define MXT_T9_MOVE(1 << 4)
-#define MXT_T9_RELEASE (1 << 5)
-#define MXT_T9_PRESS   (1 << 6)
-#define MXT_T9_DETECT  (1 << 7)
+#define MXT_T9_UNGRIP  BIT(0)
+#define MXT_T9_SUPPRESSBIT(1)
+#define MXT_T9_AMP BIT(2)
+#define MXT_T9_VECTOR  BIT(3)
+#define MXT_T9_MOVEBIT(4)
+#define MXT_T9_RELEASE BIT(5)
+#define MXT_T9_PRESS   BIT(6)
+#define MXT_T9_DETECT  BIT(7)
 
 struct t9_range {
__le16 x;
@@ -127,9 +127,9 @@ struct t9_range {
 } __packed;
 
 /* MXT_TOUCH_MULTI_T9 orient */
-#define MXT_T9_ORIENT_SWITCH   (1 << 0)
-#define MXT_T9_ORIENT_INVERTX  (1 << 1)
-#define MXT_T9_ORIENT_INVERTY  (1 << 2)
+#define MXT_T9_ORIENT_SWITCH   BIT(0)
+#define MXT_T9_ORIENT_INVERTX  BIT(1)
+#define MXT_T9_ORIENT_INVERTY  BIT(2)
 
 /* MXT_SPT_COMMSCONFIG_T18 */
 #define MXT_COMMS_CTRL 0
@@ -214,7 +214,7 @@ enum t100_type {
 #define MXT_FRAME_CRC_PASS 0x04
 #define MXT_APP_CRC_FAIL   0x40/* valid 7 8 bit only */
 #define MXT_BOOT_STATUS_MASK   0x3f
-#define MXT_BOOT_EXTENDED_ID   (1 << 5)
+#define MXT_BOOT_EXTENDED_ID   BIT(5)
 #define MXT_BOOT_ID_MASK   0x1f
 
 /* Touchscreen absolute values */
-- 
2.17.1



[PATCH v1 05/10] Input: atmel_mxt_ts - config CRC may start at T71

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

On devices with the T71 object, the config CRC will start there, rather
than at T7.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 34 +++-
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 92661aa910ae..560d4997ef8c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -75,6 +75,7 @@
 #define MXT_SPT_DIGITIZER_T43  43
 #define MXT_SPT_MESSAGECOUNT_T44   44
 #define MXT_SPT_CTECONFIG_T46  46
+#define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71
 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
 
 /* MXT_GEN_MESSAGE_T5 object */
@@ -317,6 +318,7 @@ struct mxt_data {
u8 T6_reportid;
u16 T6_address;
u16 T7_address;
+   u16 T71_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
u8 T19_reportid;
@@ -382,6 +384,7 @@ static bool mxt_object_readable(unsigned int type)
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
+   case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71:
return true;
default:
return false;
@@ -1443,6 +1446,7 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
u32 info_crc, config_crc, calculated_crc;
u8 *config_mem;
size_t config_mem_size;
+   u16 crc_start = 0;
 
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
 
@@ -1529,20 +1533,22 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
goto release_mem;
 
/* Calculate crc of the received configs (not the raw config file) */
-   if (data->T7_address < cfg_start_ofs) {
-   dev_err(dev, "Bad T7 address, T7addr = %x, config offset %x\n",
-   data->T7_address, cfg_start_ofs);
-   ret = 0;
-   goto release_mem;
-   }
+   if (data->T71_address)
+   crc_start = data->T71_address;
+   else if (data->T7_address)
+   crc_start = data->T7_address;
+   else
+   dev_warn(dev, "Could not find CRC start\n");
 
-   calculated_crc = mxt_calculate_crc(config_mem,
-  data->T7_address - cfg_start_ofs,
-  config_mem_size);
+   if (crc_start > cfg_start_ofs) {
+   calculated_crc = mxt_calculate_crc(config_mem,
+  crc_start - cfg_start_ofs,
+  config_mem_size);
 
-   if (config_crc > 0 && config_crc != calculated_crc)
-   dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n",
-calculated_crc, config_crc);
+   if (config_crc > 0 && config_crc != calculated_crc)
+   dev_warn(dev, "Config CRC in file inconsistent, 
calculated=%06X, file=%06X\n",
+calculated_crc, config_crc);
+   }
 
ret = mxt_upload_cfg_mem(data, cfg_start_ofs,
 config_mem, config_mem_size);
@@ -1589,6 +1595,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T5_msg_size = 0;
data->T6_reportid = 0;
data->T7_address = 0;
+   data->T71_address = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
data->T19_reportid = 0;
@@ -1654,6 +1661,9 @@ static int mxt_parse_object_table(struct mxt_data *data,
case MXT_GEN_POWER_T7:
data->T7_address = object->start_address;
break;
+   case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71:
+   data->T71_address = object->start_address;
+   break;
case MXT_TOUCH_MULTI_T9:
data->multitouch = MXT_TOUCH_MULTI_T9;
/* Only handle messages from first T9 instance */
-- 
2.17.1



[PATCH v1 05/10] Input: atmel_mxt_ts - config CRC may start at T71

2018-07-20 Thread Nick Dyer
From: Nick Dyer 

On devices with the T71 object, the config CRC will start there, rather
than at T7.

Signed-off-by: Nick Dyer 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 34 +++-
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 92661aa910ae..560d4997ef8c 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -75,6 +75,7 @@
 #define MXT_SPT_DIGITIZER_T43  43
 #define MXT_SPT_MESSAGECOUNT_T44   44
 #define MXT_SPT_CTECONFIG_T46  46
+#define MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71 71
 #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100
 
 /* MXT_GEN_MESSAGE_T5 object */
@@ -317,6 +318,7 @@ struct mxt_data {
u8 T6_reportid;
u16 T6_address;
u16 T7_address;
+   u16 T71_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
u8 T19_reportid;
@@ -382,6 +384,7 @@ static bool mxt_object_readable(unsigned int type)
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
+   case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71:
return true;
default:
return false;
@@ -1443,6 +1446,7 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
u32 info_crc, config_crc, calculated_crc;
u8 *config_mem;
size_t config_mem_size;
+   u16 crc_start = 0;
 
mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
 
@@ -1529,20 +1533,22 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
goto release_mem;
 
/* Calculate crc of the received configs (not the raw config file) */
-   if (data->T7_address < cfg_start_ofs) {
-   dev_err(dev, "Bad T7 address, T7addr = %x, config offset %x\n",
-   data->T7_address, cfg_start_ofs);
-   ret = 0;
-   goto release_mem;
-   }
+   if (data->T71_address)
+   crc_start = data->T71_address;
+   else if (data->T7_address)
+   crc_start = data->T7_address;
+   else
+   dev_warn(dev, "Could not find CRC start\n");
 
-   calculated_crc = mxt_calculate_crc(config_mem,
-  data->T7_address - cfg_start_ofs,
-  config_mem_size);
+   if (crc_start > cfg_start_ofs) {
+   calculated_crc = mxt_calculate_crc(config_mem,
+  crc_start - cfg_start_ofs,
+  config_mem_size);
 
-   if (config_crc > 0 && config_crc != calculated_crc)
-   dev_warn(dev, "Config CRC error, calculated=%06X, file=%06X\n",
-calculated_crc, config_crc);
+   if (config_crc > 0 && config_crc != calculated_crc)
+   dev_warn(dev, "Config CRC in file inconsistent, 
calculated=%06X, file=%06X\n",
+calculated_crc, config_crc);
+   }
 
ret = mxt_upload_cfg_mem(data, cfg_start_ofs,
 config_mem, config_mem_size);
@@ -1589,6 +1595,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T5_msg_size = 0;
data->T6_reportid = 0;
data->T7_address = 0;
+   data->T71_address = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
data->T19_reportid = 0;
@@ -1654,6 +1661,9 @@ static int mxt_parse_object_table(struct mxt_data *data,
case MXT_GEN_POWER_T7:
data->T7_address = object->start_address;
break;
+   case MXT_SPT_DYNAMICCONFIGURATIONCONTAINER_T71:
+   data->T71_address = object->start_address;
+   break;
case MXT_TOUCH_MULTI_T9:
data->multitouch = MXT_TOUCH_MULTI_T9;
/* Only handle messages from first T9 instance */
-- 
2.17.1



Re: [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.

2018-07-19 Thread Nick Dyer
On Wed, Jul 18, 2018 at 06:21:30PM +0200, Paweł Chmiel wrote:
> On Tuesday, July 17, 2018 10:00:05 PM CEST Nick Dyer wrote:
> > On Tue, Jul 17, 2018 at 08:16:25PM +0200, Paweł Chmiel wrote:
> > > This patch adds optional regulators, which can be used to power
> > > up touchscreen. After enabling regulators, we need to wait 150msec.
> > > This value is taken from official driver.
> > > 
> > > It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
> > > 
> > > Signed-off-by: Paweł Chmiel 
> > > ---
> > > Changes from v1:
> > >   - Enable regulators only if reset_gpio is present.
> > >   - Switch from devm_regulator_get_optional to devm_regulator_get
> > > ---
> > >  drivers/input/touchscreen/atmel_mxt_ts.c | 46 
> > > ++--
> > >  1 file changed, 44 insertions(+), 2 deletions(-)
> > 
> > Hi Pawel-
> > 
> > I see you've borrowed some of the logic from the patch I wrote a while
> > back (see https://github.com/ndyer/linux/commit/8e9687e41ed062 )
> Actually, i was looking at 
> https://github.com/atmel-maxtouch/linux/blob/maxtouch-v3.14/drivers/input/touchscreen/atmel_mxt_ts.c
>  (and didn't saw Your patch till now).
> Are You going to submit it? (it has more functionalities - for example
> suspend mode read from device tree).

Getting that work upstream has stalled for a couple of years because I
changed jobs. I have actually started recently to dust it off again, it
was later on in my queue but if you have the time to work on it that is
great.

> > The correct behaviour according to Atmel should be:
> > 
> > * Make RESET zero
> > * Bring up regulators
> > * Wait for a period to settle (150 msec)
> > * Release RESET
> > * Wait for 100 msec whilst device gets through bootloader
> > * Wait for CHG line assert before reading info block
> > 
> > I can't see the first and last steps in your patch at present.
> About first step - reset_gpio is readed by using
> devm_gpiod_get_optional with GPIOD_OUT_LOW flag, so i think (but might
> be wrong)  that we don't need to set this gpio value again to 0 before
> enabling regulators,

I see what you mean - that is fair enough.

> since currently only place where reset_gpio is used is in driver probe
> (in Your patch it is used in other cases/places - for example in
> mxt_start/stop, when we enable regulators).
> About missing wait after releasing reset, shouldn't this be separate
> patch (since currently driver is not doing it)? I can prepare it and
> send with other in next version.

According to the maxtouch documentation, it isn't ready for comms until
the firmware asserts the CHG line. I've seen a bunch of devices that get
by without an explicit wait because the board file does the power on,
and by the time the driver gets to probe it's a few hundred ms later
anyway, so it doesn't matter. But if we put it all in the driver, it
will attempt to read the info block straight after the 100 msec delay
without waiting for CHG, and I suspect we'll end up with occasional
probe failures. It'll depend on the maxtouch device, though: they have a
range of different power on timings.

Which platform are you doing this for? Is it a Chromebook?

> Thanks for feedback
> > 
> > The only downside with this approach is that there are a lot of
> > delays during driver probe, but I believe the asynchronous probe stuff
> > that's landed since I wrote the original patch should address that.
> > 
> > cheers
> > 
> > Nick
> > 
> > >   }
> > > @@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
> > >   struct mxt_data *data = i2c_get_clientdata(client);
> > >  
> > >   disable_irq(data->irq);
> > > + if (data->reset_gpio) {
> > > + regulator_disable(data->avdd_reg);
> > > + regulator_disable(data->vdd_reg);
> > > + }
> > >   sysfs_remove_group(>dev.kobj, _attr_group);
> > >   mxt_free_input_device(data);
> > >   mxt_free_object_table(data);
> > 
> 
> 


Re: [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.

2018-07-19 Thread Nick Dyer
On Wed, Jul 18, 2018 at 06:21:30PM +0200, Paweł Chmiel wrote:
> On Tuesday, July 17, 2018 10:00:05 PM CEST Nick Dyer wrote:
> > On Tue, Jul 17, 2018 at 08:16:25PM +0200, Paweł Chmiel wrote:
> > > This patch adds optional regulators, which can be used to power
> > > up touchscreen. After enabling regulators, we need to wait 150msec.
> > > This value is taken from official driver.
> > > 
> > > It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
> > > 
> > > Signed-off-by: Paweł Chmiel 
> > > ---
> > > Changes from v1:
> > >   - Enable regulators only if reset_gpio is present.
> > >   - Switch from devm_regulator_get_optional to devm_regulator_get
> > > ---
> > >  drivers/input/touchscreen/atmel_mxt_ts.c | 46 
> > > ++--
> > >  1 file changed, 44 insertions(+), 2 deletions(-)
> > 
> > Hi Pawel-
> > 
> > I see you've borrowed some of the logic from the patch I wrote a while
> > back (see https://github.com/ndyer/linux/commit/8e9687e41ed062 )
> Actually, i was looking at 
> https://github.com/atmel-maxtouch/linux/blob/maxtouch-v3.14/drivers/input/touchscreen/atmel_mxt_ts.c
>  (and didn't saw Your patch till now).
> Are You going to submit it? (it has more functionalities - for example
> suspend mode read from device tree).

Getting that work upstream has stalled for a couple of years because I
changed jobs. I have actually started recently to dust it off again, it
was later on in my queue but if you have the time to work on it that is
great.

> > The correct behaviour according to Atmel should be:
> > 
> > * Make RESET zero
> > * Bring up regulators
> > * Wait for a period to settle (150 msec)
> > * Release RESET
> > * Wait for 100 msec whilst device gets through bootloader
> > * Wait for CHG line assert before reading info block
> > 
> > I can't see the first and last steps in your patch at present.
> About first step - reset_gpio is readed by using
> devm_gpiod_get_optional with GPIOD_OUT_LOW flag, so i think (but might
> be wrong)  that we don't need to set this gpio value again to 0 before
> enabling regulators,

I see what you mean - that is fair enough.

> since currently only place where reset_gpio is used is in driver probe
> (in Your patch it is used in other cases/places - for example in
> mxt_start/stop, when we enable regulators).
> About missing wait after releasing reset, shouldn't this be separate
> patch (since currently driver is not doing it)? I can prepare it and
> send with other in next version.

According to the maxtouch documentation, it isn't ready for comms until
the firmware asserts the CHG line. I've seen a bunch of devices that get
by without an explicit wait because the board file does the power on,
and by the time the driver gets to probe it's a few hundred ms later
anyway, so it doesn't matter. But if we put it all in the driver, it
will attempt to read the info block straight after the 100 msec delay
without waiting for CHG, and I suspect we'll end up with occasional
probe failures. It'll depend on the maxtouch device, though: they have a
range of different power on timings.

Which platform are you doing this for? Is it a Chromebook?

> Thanks for feedback
> > 
> > The only downside with this approach is that there are a lot of
> > delays during driver probe, but I believe the asynchronous probe stuff
> > that's landed since I wrote the original patch should address that.
> > 
> > cheers
> > 
> > Nick
> > 
> > >   }
> > > @@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
> > >   struct mxt_data *data = i2c_get_clientdata(client);
> > >  
> > >   disable_irq(data->irq);
> > > + if (data->reset_gpio) {
> > > + regulator_disable(data->avdd_reg);
> > > + regulator_disable(data->vdd_reg);
> > > + }
> > >   sysfs_remove_group(>dev.kobj, _attr_group);
> > >   mxt_free_input_device(data);
> > >   mxt_free_object_table(data);
> > 
> 
> 


Re: [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.

2018-07-17 Thread Nick Dyer
On Tue, Jul 17, 2018 at 08:16:25PM +0200, Paweł Chmiel wrote:
> This patch adds optional regulators, which can be used to power
> up touchscreen. After enabling regulators, we need to wait 150msec.
> This value is taken from official driver.
> 
> It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
> 
> Signed-off-by: Paweł Chmiel 
> ---
> Changes from v1:
>   - Enable regulators only if reset_gpio is present.
>   - Switch from devm_regulator_get_optional to devm_regulator_get
> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 46 
> ++--
>  1 file changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 54fe190fd4bc..005f0fee9fc8 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -27,6 +27,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -194,10 +195,10 @@ enum t100_type {
>  
>  /* Delay times */
>  #define MXT_BACKUP_TIME  50  /* msec */
> -#define MXT_RESET_GPIO_TIME  20  /* msec */
>  #define MXT_RESET_INVALID_CHG100 /* msec */
>  #define MXT_RESET_TIME   200 /* msec */
>  #define MXT_RESET_TIMEOUT3000/* msec */
> +#define MXT_REGULATOR_DELAY  150 /* msec */
>  #define MXT_CRC_TIMEOUT  1000/* msec */
>  #define MXT_FW_RESET_TIME3000/* msec */
>  #define MXT_FW_CHG_TIMEOUT   300 /* msec */
> @@ -310,6 +311,8 @@ struct mxt_data {
>   struct t7_config t7_cfg;
>   struct mxt_dbg dbg;
>   struct gpio_desc *reset_gpio;
> + struct regulator *vdd_reg;
> + struct regulator *avdd_reg;
>  
>   /* Cached parameters from object table */
>   u16 T5_address;
> @@ -3076,6 +3079,22 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   return error;
>   }
>  
> + data->vdd_reg = devm_regulator_get(>dev, "vdd");
> + if (IS_ERR(data->vdd_reg)) {
> + error = PTR_ERR(data->vdd_reg);
> + dev_err(>dev, "Failed to get vdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
> + data->avdd_reg = devm_regulator_get(>dev, "avdd");
> + if (IS_ERR(data->avdd_reg)) {
> + error = PTR_ERR(data->avdd_reg);
> + dev_err(>dev, "Failed to get avdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
>   error = devm_request_threaded_irq(>dev, client->irq,
> NULL, mxt_interrupt, IRQF_ONESHOT,
> client->name, data);
> @@ -3087,7 +3106,26 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   disable_irq(client->irq);
>  
>   if (data->reset_gpio) {
> - msleep(MXT_RESET_GPIO_TIME);
> + error = regulator_enable(data->vdd_reg);
> + if (error) {
> + dev_err(>dev, "Failed to enable vdd regulator: 
> %d\n",
> + error);
> + return error;
> + }
> +
> + error = regulator_enable(data->avdd_reg);
> + if (error) {
> + dev_err(>dev, "Failed to enable avdd regulator: 
> %d\n",
> + error);
> + return error;
> + }
> +
> + /*
> +  * According to maXTouch power sequencing specification, RESET 
> line
> +  * must be kept low until some time after regulators come up to
> +  * voltage
> +  */
> + msleep(MXT_REGULATOR_DELAY);
>   gpiod_set_value(data->reset_gpio, 1);
>   msleep(MXT_RESET_INVALID_CHG);

Hi Pawel-

I see you've borrowed some of the logic from the patch I wrote a while
back (see https://github.com/ndyer/linux/commit/8e9687e41ed062 )

The correct behaviour according to Atmel should be:

* Make RESET zero
* Bring up regulators
* Wait for a period to settle (150 msec)
* Release RESET
* Wait for 100 msec whilst device gets through bootloader
* Wait for CHG line assert before reading info block

I can't see the first and last steps in your patch at present.

The only downside with this approach is that there are a lot of
delays during driver probe, but I believe the asynchronous probe stuff
that's landed since I wrote the original patch should address that.

cheers

Nick

>   }
> @@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
>   struct mxt_data *data = i2c_get_clientdata(client);
>  
>   disable_irq(data->irq);
> + if (data->reset_gpio) {
> + regulator_disable(data->avdd_reg);
> + regulator_disable(data->vdd_reg);
> + }
>   sysfs_remove_group(>dev.kobj, _attr_group);
>   

Re: [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.

2018-07-17 Thread Nick Dyer
On Tue, Jul 17, 2018 at 08:16:25PM +0200, Paweł Chmiel wrote:
> This patch adds optional regulators, which can be used to power
> up touchscreen. After enabling regulators, we need to wait 150msec.
> This value is taken from official driver.
> 
> It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
> 
> Signed-off-by: Paweł Chmiel 
> ---
> Changes from v1:
>   - Enable regulators only if reset_gpio is present.
>   - Switch from devm_regulator_get_optional to devm_regulator_get
> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 46 
> ++--
>  1 file changed, 44 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 54fe190fd4bc..005f0fee9fc8 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -27,6 +27,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -194,10 +195,10 @@ enum t100_type {
>  
>  /* Delay times */
>  #define MXT_BACKUP_TIME  50  /* msec */
> -#define MXT_RESET_GPIO_TIME  20  /* msec */
>  #define MXT_RESET_INVALID_CHG100 /* msec */
>  #define MXT_RESET_TIME   200 /* msec */
>  #define MXT_RESET_TIMEOUT3000/* msec */
> +#define MXT_REGULATOR_DELAY  150 /* msec */
>  #define MXT_CRC_TIMEOUT  1000/* msec */
>  #define MXT_FW_RESET_TIME3000/* msec */
>  #define MXT_FW_CHG_TIMEOUT   300 /* msec */
> @@ -310,6 +311,8 @@ struct mxt_data {
>   struct t7_config t7_cfg;
>   struct mxt_dbg dbg;
>   struct gpio_desc *reset_gpio;
> + struct regulator *vdd_reg;
> + struct regulator *avdd_reg;
>  
>   /* Cached parameters from object table */
>   u16 T5_address;
> @@ -3076,6 +3079,22 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   return error;
>   }
>  
> + data->vdd_reg = devm_regulator_get(>dev, "vdd");
> + if (IS_ERR(data->vdd_reg)) {
> + error = PTR_ERR(data->vdd_reg);
> + dev_err(>dev, "Failed to get vdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
> + data->avdd_reg = devm_regulator_get(>dev, "avdd");
> + if (IS_ERR(data->avdd_reg)) {
> + error = PTR_ERR(data->avdd_reg);
> + dev_err(>dev, "Failed to get avdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
>   error = devm_request_threaded_irq(>dev, client->irq,
> NULL, mxt_interrupt, IRQF_ONESHOT,
> client->name, data);
> @@ -3087,7 +3106,26 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   disable_irq(client->irq);
>  
>   if (data->reset_gpio) {
> - msleep(MXT_RESET_GPIO_TIME);
> + error = regulator_enable(data->vdd_reg);
> + if (error) {
> + dev_err(>dev, "Failed to enable vdd regulator: 
> %d\n",
> + error);
> + return error;
> + }
> +
> + error = regulator_enable(data->avdd_reg);
> + if (error) {
> + dev_err(>dev, "Failed to enable avdd regulator: 
> %d\n",
> + error);
> + return error;
> + }
> +
> + /*
> +  * According to maXTouch power sequencing specification, RESET 
> line
> +  * must be kept low until some time after regulators come up to
> +  * voltage
> +  */
> + msleep(MXT_REGULATOR_DELAY);
>   gpiod_set_value(data->reset_gpio, 1);
>   msleep(MXT_RESET_INVALID_CHG);

Hi Pawel-

I see you've borrowed some of the logic from the patch I wrote a while
back (see https://github.com/ndyer/linux/commit/8e9687e41ed062 )

The correct behaviour according to Atmel should be:

* Make RESET zero
* Bring up regulators
* Wait for a period to settle (150 msec)
* Release RESET
* Wait for 100 msec whilst device gets through bootloader
* Wait for CHG line assert before reading info block

I can't see the first and last steps in your patch at present.

The only downside with this approach is that there are a lot of
delays during driver probe, but I believe the asynchronous probe stuff
that's landed since I wrote the original patch should address that.

cheers

Nick

>   }
> @@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
>   struct mxt_data *data = i2c_get_clientdata(client);
>  
>   disable_irq(data->irq);
> + if (data->reset_gpio) {
> + regulator_disable(data->avdd_reg);
> + regulator_disable(data->vdd_reg);
> + }
>   sysfs_remove_group(>dev.kobj, _attr_group);
>   

[PATCH v1] ARM: dts: imx51-zii-rdu1: correct touchscreen axis inversion

2018-06-28 Thread Nick Dyer
The RMI4 touchscreen driver applied inversion and axis swap in the
wrong order, violating the DT binding for those properties. This was fixed in
645a397, so correct the RDU1 DT to apply the inversion to the
correct axis.

Tested on Zii RDU1 00-5105-30 rev B

Signed-off-by: Nick Dyer 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 68f5c1d5ecd0..b1d83fb08150 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -553,7 +553,7 @@
 
rmi4-f11@11 {
reg = <0x11>;
-   touchscreen-inverted-y;
+   touchscreen-inverted-x;
touchscreen-swapped-x-y;
syna,sensor-type = <1>;
};
-- 
2.17.1



[PATCH v1] ARM: dts: imx51-zii-rdu1: correct touchscreen axis inversion

2018-06-28 Thread Nick Dyer
The RMI4 touchscreen driver applied inversion and axis swap in the
wrong order, violating the DT binding for those properties. This was fixed in
645a397, so correct the RDU1 DT to apply the inversion to the
correct axis.

Tested on Zii RDU1 00-5105-30 rev B

Signed-off-by: Nick Dyer 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index 68f5c1d5ecd0..b1d83fb08150 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -553,7 +553,7 @@
 
rmi4-f11@11 {
reg = <0x11>;
-   touchscreen-inverted-y;
+   touchscreen-inverted-x;
touchscreen-swapped-x-y;
syna,sensor-type = <1>;
};
-- 
2.17.1



[PATCH v5] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-21 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
from the old vendor kernel.

Signed-off-by: Nick Dyer 
Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
Cc:  # 4.15+
Reviewed-by: Fabio Estevam 
Tested-by: Chris Healy 
---
Changes in v5:
- Add tested by Chris Healy
Changes in v4:
- Add reviewed by Fabio
Changes in v3:
- Update commit message to add source of 0x4 value, fixes tag and CC stable
Changes in v2:
- Use hex, only alter IRQ line config

 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v5] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-21 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
from the old vendor kernel.

Signed-off-by: Nick Dyer 
Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
Cc:  # 4.15+
Reviewed-by: Fabio Estevam 
Tested-by: Chris Healy 
---
Changes in v5:
- Add tested by Chris Healy
Changes in v4:
- Add reviewed by Fabio
Changes in v3:
- Update commit message to add source of 0x4 value, fixes tag and CC stable
Changes in v2:
- Use hex, only alter IRQ line config

 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v4] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-20 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
from the old vendor kernel.

Signed-off-by: Nick Dyer 
Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
Cc:  # 4.15+
Reviewed-by: Fabio Estevam 
---
Changes in v4:
- Add reviewed by Fabio
Changes in v3:
- Update commit message to add source of 0x4 value, fixes tag and CC stable
Changes in v2:
- Use hex, only alter IRQ line config

 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v4] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-20 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
from the old vendor kernel.

Signed-off-by: Nick Dyer 
Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
Cc:  # 4.15+
Reviewed-by: Fabio Estevam 
---
Changes in v4:
- Add reviewed by Fabio
Changes in v3:
- Update commit message to add source of 0x4 value, fixes tag and CC stable
Changes in v2:
- Use hex, only alter IRQ line config

 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v3] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-20 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
from the old vendor kernel.

Signed-off-by: Nick Dyer 
Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
Cc:  # 4.15+
---
Changes in v3:
- Update commit message to add source of 0x4 value, fixes tag and CC stable
Changes in v2:
- Use hex, only alter IRQ line config

 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v3] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-20 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
from the old vendor kernel.

Signed-off-by: Nick Dyer 
Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
Cc:  # 4.15+
---
Changes in v3:
- Update commit message to add source of 0x4 value, fixes tag and CC stable
Changes in v2:
- Use hex, only alter IRQ line config

 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v2] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-20 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

[v2: Use hex, only alter IRQ line config]

Signed-off-by: Nick Dyer 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v2] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-20 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

[v2: Use hex, only alter IRQ line config]

Signed-off-by: Nick Dyer 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..8a878687197b 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,7 +770,7 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  0x04
MX51_PAD_CSI1_D9__GPIO3_13  0x85
>;
};
-- 
2.17.1



[PATCH v1] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-19 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

Signed-off-by: Nick Dyer 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..4d12ba54ba15 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,8 +770,8 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
-   MX51_PAD_CSI1_D9__GPIO3_13  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  4
+   MX51_PAD_CSI1_D9__GPIO3_13  (1<<16)
>;
};
 
-- 
2.17.1



[PATCH v1] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl

2018-06-19 Thread Nick Dyer
The pinctrl settings were incorrect for the touchscreen interrupt line, causing
an interrupt storm. This change has been tested with both the atmel_mxt_ts and
RMI4 drivers on the RDU1 units.

Signed-off-by: Nick Dyer 
---
 arch/arm/boot/dts/imx51-zii-rdu1.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/imx51-zii-rdu1.dts 
b/arch/arm/boot/dts/imx51-zii-rdu1.dts
index df9eca94d812..4d12ba54ba15 100644
--- a/arch/arm/boot/dts/imx51-zii-rdu1.dts
+++ b/arch/arm/boot/dts/imx51-zii-rdu1.dts
@@ -770,8 +770,8 @@
 
pinctrl_ts: tsgrp {
fsl,pins = <
-   MX51_PAD_CSI1_D8__GPIO3_12  0x85
-   MX51_PAD_CSI1_D9__GPIO3_13  0x85
+   MX51_PAD_CSI1_D8__GPIO3_12  4
+   MX51_PAD_CSI1_D9__GPIO3_13  (1<<16)
>;
};
 
-- 
2.17.1



Re: [PATCH] Input: atmel_mxt_ts - fix reset-gpio for level based irqs

2018-04-21 Thread Nick Dyer
On Fri, Apr 20, 2018 at 09:42:07PM +0200, Sebastian Reichel wrote:
> On Fri, Apr 20, 2018 at 02:44:02PM -0300, Ezequiel Garcia wrote:
> > Hi Sebastian,
> > 
> > On Fri, 2018-04-20 at 19:24 +0200, Sebastian Reichel wrote:
> > > The current reset-gpio support triggers an interrupt storm on platforms
> > > using the maxtouch with level based interrupt. The Motorola Droid 4,
> > > which I used for some of the tests is not affected, since it uses a level
> > > based interrupt.
> > > 
> > 
> > I found this confusing. Interrupt storm happen with level-based interrupts,
> > but the Droid4 is not affected?

Can I ask what happens during the interrupt storm. Are you getting lots
of the "failed to read T44 and T5" message, or something else?

> > > This change avoids the interrupt storm by enabling the device while
> > > its interrupt is disabled. The following mxt_initialize() requires,
> > > that the device is responsive (at least mxt224E is unresponsive for
> > > ~22ms), so we wait some time. We don't wait for leaving bootloader
> > > mode anymore, since mxt_initialize() checks for it anyways.
> > > 
> > 
> > IMHO, having some more or less arbritrary sleeps is almost
> > always a problem. This value might be enough for some platform,
> > might be too short for some other, and then it might get too large
> > for someone else.
> 
> The 22ms chip-being-unresponsive are not newly introduced. The
> same 22ms are also required for soft-reset. I did introduce a
> new time (MXT_RESET_GPIO_TIME) for the "chip being reset" state,
> since my randomly chosen 200ms from before were exaggerated
> considering all mxt datasheets I checked stated only a few nano
> seconds.

According to the data sheets there is a period after a reset where the
CHG line is temporarily set as an input, during which the host should
ignore it. If you don't, you might get a stray interrupt and try and
communicate with the device, which might leave it in a bad state. I
think you mentioned that later in your email.

The reset time varies per chip, but the 100ms in mxt_soft_reset() was
based on discussions with app support at Atmel, so should be correct in
most cases.


Re: [PATCH] Input: atmel_mxt_ts - fix reset-gpio for level based irqs

2018-04-21 Thread Nick Dyer
On Fri, Apr 20, 2018 at 09:42:07PM +0200, Sebastian Reichel wrote:
> On Fri, Apr 20, 2018 at 02:44:02PM -0300, Ezequiel Garcia wrote:
> > Hi Sebastian,
> > 
> > On Fri, 2018-04-20 at 19:24 +0200, Sebastian Reichel wrote:
> > > The current reset-gpio support triggers an interrupt storm on platforms
> > > using the maxtouch with level based interrupt. The Motorola Droid 4,
> > > which I used for some of the tests is not affected, since it uses a level
> > > based interrupt.
> > > 
> > 
> > I found this confusing. Interrupt storm happen with level-based interrupts,
> > but the Droid4 is not affected?

Can I ask what happens during the interrupt storm. Are you getting lots
of the "failed to read T44 and T5" message, or something else?

> > > This change avoids the interrupt storm by enabling the device while
> > > its interrupt is disabled. The following mxt_initialize() requires,
> > > that the device is responsive (at least mxt224E is unresponsive for
> > > ~22ms), so we wait some time. We don't wait for leaving bootloader
> > > mode anymore, since mxt_initialize() checks for it anyways.
> > > 
> > 
> > IMHO, having some more or less arbritrary sleeps is almost
> > always a problem. This value might be enough for some platform,
> > might be too short for some other, and then it might get too large
> > for someone else.
> 
> The 22ms chip-being-unresponsive are not newly introduced. The
> same 22ms are also required for soft-reset. I did introduce a
> new time (MXT_RESET_GPIO_TIME) for the "chip being reset" state,
> since my randomly chosen 200ms from before were exaggerated
> considering all mxt datasheets I checked stated only a few nano
> seconds.

According to the data sheets there is a period after a reset where the
CHG line is temporarily set as an input, during which the host should
ignore it. If you don't, you might get a stray interrupt and try and
communicate with the device, which might leave it in a bad state. I
think you mentioned that later in your email.

The reset time varies per chip, but the 100ms in mxt_soft_reset() was
based on discussions with app support at Atmel, so should be correct in
most cases.


Re: [PATCHv1] Input: atmel_mxt_ts - fix the firmware update

2018-03-23 Thread Nick Dyer
On Thu, Mar 22, 2018 at 05:43:30PM +0100, Sebastian Reichel wrote:
> The automatic update mechanism will trigger an update if the
> info block CRCs are different between maxtouch configuration
> file (maxtouch.cfg) and chip.
> 
> The driver compared the CRCs without retrieving the chip CRC,
> resulting always in a failure and firmware flashing action
> triggered. The patch will fix this issue by retrieving the
> chip info block CRC before the check.

Thanks for raising this, I agree it's definitely something we want to
fix.

However, I'm not convinced you're solving the problem in the best way.
You've attached it to the read_t9_resolution() code path, whereas the
info block is common between T9 and T100 and works in the same way.

Would you mind trying the below patch? I've dusted it off from some
work that I did back in 2012 and it should solve your issue.

It also has the benefit that by reading the information block and the
object table into a contiguous region of memory, we can verify the
checksum at probe time. This means we make sure that we are indeed
talking to a chip that supports object protocol correctly.

Signed-off-by: Nick Dyer <nick.d...@shmanahar.org>
Acked-by: Benson Leung <ble...@chromium.org>
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 193 +++
 1 file changed, 117 insertions(+), 76 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7659bc48f1db..8a60d91d49a6 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -275,7 +275,8 @@ struct mxt_data {
char phys[64];  /* device physical location */
const struct mxt_platform_data *pdata;
struct mxt_object *object_table;
-   struct mxt_info info;
+   struct mxt_info *info;
+   void *raw_info_block;
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -450,12 +451,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data 
*data, bool retry)
 {
u8 appmode = data->client->addr;
u8 bootloader;
+   u8 family_id = data->info ? data->info->family_id : 0;
 
switch (appmode) {
case 0x4a:
case 0x4b:
/* Chips after 1664S use different scheme */
-   if (retry || data->info.family_id >= 0xa2) {
+   if (retry || family_id >= 0xa2) {
bootloader = appmode - 0x24;
break;
}
@@ -682,7 +684,7 @@ mxt_get_object(struct mxt_data *data, u8 type)
struct mxt_object *object;
int i;
 
-   for (i = 0; i < data->info.object_num; i++) {
+   for (i = 0; i < data->info->object_num; i++) {
object = data->object_table + i;
if (object->type == type)
return object;
@@ -1453,12 +1455,12 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
data_pos += offset;
}
 
-   if (cfg_info.family_id != data->info.family_id) {
+   if (cfg_info.family_id != data->info->family_id) {
dev_err(dev, "Family ID mismatch!\n");
return -EINVAL;
}
 
-   if (cfg_info.variant_id != data->info.variant_id) {
+   if (cfg_info.variant_id != data->info->variant_id) {
dev_err(dev, "Variant ID mismatch!\n");
return -EINVAL;
}
@@ -1503,7 +1505,7 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
 
/* Malloc memory to store configuration */
cfg_start_ofs = MXT_OBJECT_START +
-   data->info.object_num * sizeof(struct mxt_object) +
+   data->info->object_num * sizeof(struct mxt_object) +
MXT_INFO_CHECKSUM_SIZE;
config_mem_size = data->mem_size - cfg_start_ofs;
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
@@ -1554,20 +1556,6 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
return ret;
 }
 
-static int mxt_get_info(struct mxt_data *data)
-{
-   struct i2c_client *client = data->client;
-   struct mxt_info *info = >info;
-   int error;
-
-   /* Read 7-byte info block starting at address 0 */
-   error = __mxt_read_reg(client, 0, sizeof(*info), info);
-   if (error)
-   return error;
-
-   return 0;
-}
-
 static void mxt_free_input_device(struct mxt_data *data)
 {
if (data->input_dev) {
@@ -1582,9 +1570,10 @@ static void mxt_free_object_table(struct mxt_data *data)
video_unregister_device(>dbg.vdev);
v4l2_device_unregister(>dbg.v4l2);
 #endif
-
-   kfree(data->object_table);
data->object_table = NULL;
+   data->info = NULL;
+  

Re: [PATCHv1] Input: atmel_mxt_ts - fix the firmware update

2018-03-23 Thread Nick Dyer
On Thu, Mar 22, 2018 at 05:43:30PM +0100, Sebastian Reichel wrote:
> The automatic update mechanism will trigger an update if the
> info block CRCs are different between maxtouch configuration
> file (maxtouch.cfg) and chip.
> 
> The driver compared the CRCs without retrieving the chip CRC,
> resulting always in a failure and firmware flashing action
> triggered. The patch will fix this issue by retrieving the
> chip info block CRC before the check.

Thanks for raising this, I agree it's definitely something we want to
fix.

However, I'm not convinced you're solving the problem in the best way.
You've attached it to the read_t9_resolution() code path, whereas the
info block is common between T9 and T100 and works in the same way.

Would you mind trying the below patch? I've dusted it off from some
work that I did back in 2012 and it should solve your issue.

It also has the benefit that by reading the information block and the
object table into a contiguous region of memory, we can verify the
checksum at probe time. This means we make sure that we are indeed
talking to a chip that supports object protocol correctly.

Signed-off-by: Nick Dyer 
Acked-by: Benson Leung 
---
 drivers/input/touchscreen/atmel_mxt_ts.c | 193 +++
 1 file changed, 117 insertions(+), 76 deletions(-)

diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
b/drivers/input/touchscreen/atmel_mxt_ts.c
index 7659bc48f1db..8a60d91d49a6 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -275,7 +275,8 @@ struct mxt_data {
char phys[64];  /* device physical location */
const struct mxt_platform_data *pdata;
struct mxt_object *object_table;
-   struct mxt_info info;
+   struct mxt_info *info;
+   void *raw_info_block;
unsigned int irq;
unsigned int max_x;
unsigned int max_y;
@@ -450,12 +451,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data 
*data, bool retry)
 {
u8 appmode = data->client->addr;
u8 bootloader;
+   u8 family_id = data->info ? data->info->family_id : 0;
 
switch (appmode) {
case 0x4a:
case 0x4b:
/* Chips after 1664S use different scheme */
-   if (retry || data->info.family_id >= 0xa2) {
+   if (retry || family_id >= 0xa2) {
bootloader = appmode - 0x24;
break;
}
@@ -682,7 +684,7 @@ mxt_get_object(struct mxt_data *data, u8 type)
struct mxt_object *object;
int i;
 
-   for (i = 0; i < data->info.object_num; i++) {
+   for (i = 0; i < data->info->object_num; i++) {
object = data->object_table + i;
if (object->type == type)
return object;
@@ -1453,12 +1455,12 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
data_pos += offset;
}
 
-   if (cfg_info.family_id != data->info.family_id) {
+   if (cfg_info.family_id != data->info->family_id) {
dev_err(dev, "Family ID mismatch!\n");
return -EINVAL;
}
 
-   if (cfg_info.variant_id != data->info.variant_id) {
+   if (cfg_info.variant_id != data->info->variant_id) {
dev_err(dev, "Variant ID mismatch!\n");
return -EINVAL;
}
@@ -1503,7 +1505,7 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
 
/* Malloc memory to store configuration */
cfg_start_ofs = MXT_OBJECT_START +
-   data->info.object_num * sizeof(struct mxt_object) +
+   data->info->object_num * sizeof(struct mxt_object) +
MXT_INFO_CHECKSUM_SIZE;
config_mem_size = data->mem_size - cfg_start_ofs;
config_mem = kzalloc(config_mem_size, GFP_KERNEL);
@@ -1554,20 +1556,6 @@ static int mxt_update_cfg(struct mxt_data *data, const 
struct firmware *cfg)
return ret;
 }
 
-static int mxt_get_info(struct mxt_data *data)
-{
-   struct i2c_client *client = data->client;
-   struct mxt_info *info = >info;
-   int error;
-
-   /* Read 7-byte info block starting at address 0 */
-   error = __mxt_read_reg(client, 0, sizeof(*info), info);
-   if (error)
-   return error;
-
-   return 0;
-}
-
 static void mxt_free_input_device(struct mxt_data *data)
 {
if (data->input_dev) {
@@ -1582,9 +1570,10 @@ static void mxt_free_object_table(struct mxt_data *data)
video_unregister_device(>dbg.vdev);
v4l2_device_unregister(>dbg.v4l2);
 #endif
-
-   kfree(data->object_table);
data->object_table = NULL;
+   data->info = NULL;
+   kfree(data->raw_info_block);
+   data->

Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data

2018-03-17 Thread Nick Dyer
On Sat, Mar 17, 2018 at 10:42:40AM -0700, Dmitry Torokhov wrote:
> On Fri, Mar 16, 2018 at 08:40:02PM +0000, Nick Dyer wrote:
> > On Thu, Mar 15, 2018 at 04:56:21PM -0700, Dmitry Torokhov wrote:
> > > Ah, OK, I see. I would really like to drop this
> > > pdata->suspend_mode stuff and I do not want to create
> > > "pixel-screwed-up" property either...  I guess for the time being
> > > I'll put a DMI quirk for Link to restore T9 control method, and
> > > then look into cleaning it all up. We have quite a bit different
> > > code in chromeos kernel trees and I'd like to reconcile
> > > it.
> > 
> > Yes, it would be great to get rid of it. The driver does have the
> > ability to download configuration via the firmware loader interface.
> > So you would be able to grab a copy of the config by saving it with
> > mxt-app, tweak it to ensure that the T9 CTRL byte is set correctly,
> > then ship it somehow (presumably it could be added to
> > linux-firmware). This would override what's currently stored in
> > NVRAM on all those units and mean we could remove the T9_CTRL stuff.
> 
> We can't really rely on people fetching updated config. Do you think we
> could see if the device has only T9 and not T100 and if coming out of
> suspend the T9 CTRL byte is 0 we overwrite it with the 0x83?

I think that all we need to do is add something to
mxt_read_t9_resolution (and probably rename it to mxt_init_t9_config)
that reads the 1st (CTRL) byte, and if it's zero, writes 0x83 (and
probably a dev_dbg() wouldn't go amiss)

Also call the same logic on reset (look for "Detect reset"), because
that wipes out the config.

Once we've done that, we can get rid of the MXT_SUSPEND_T9_CTRL and use
the normal T7 power up/down logic for suspend/resume on all devices.

FWIW there may be two instances of T9, but I've never seen a device that
actually had two screens and it's not supported really anyway with this
driver.

N


Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data

2018-03-17 Thread Nick Dyer
On Sat, Mar 17, 2018 at 10:42:40AM -0700, Dmitry Torokhov wrote:
> On Fri, Mar 16, 2018 at 08:40:02PM +0000, Nick Dyer wrote:
> > On Thu, Mar 15, 2018 at 04:56:21PM -0700, Dmitry Torokhov wrote:
> > > Ah, OK, I see. I would really like to drop this
> > > pdata->suspend_mode stuff and I do not want to create
> > > "pixel-screwed-up" property either...  I guess for the time being
> > > I'll put a DMI quirk for Link to restore T9 control method, and
> > > then look into cleaning it all up. We have quite a bit different
> > > code in chromeos kernel trees and I'd like to reconcile
> > > it.
> > 
> > Yes, it would be great to get rid of it. The driver does have the
> > ability to download configuration via the firmware loader interface.
> > So you would be able to grab a copy of the config by saving it with
> > mxt-app, tweak it to ensure that the T9 CTRL byte is set correctly,
> > then ship it somehow (presumably it could be added to
> > linux-firmware). This would override what's currently stored in
> > NVRAM on all those units and mean we could remove the T9_CTRL stuff.
> 
> We can't really rely on people fetching updated config. Do you think we
> could see if the device has only T9 and not T100 and if coming out of
> suspend the T9 CTRL byte is 0 we overwrite it with the 0x83?

I think that all we need to do is add something to
mxt_read_t9_resolution (and probably rename it to mxt_init_t9_config)
that reads the 1st (CTRL) byte, and if it's zero, writes 0x83 (and
probably a dev_dbg() wouldn't go amiss)

Also call the same logic on reset (look for "Detect reset"), because
that wipes out the config.

Once we've done that, we can get rid of the MXT_SUSPEND_T9_CTRL and use
the normal T7 power up/down logic for suspend/resume on all devices.

FWIW there may be two instances of T9, but I've never seen a device that
actually had two screens and it's not supported really anyway with this
driver.

N


Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data

2018-03-16 Thread Nick Dyer
On Thu, Mar 15, 2018 at 04:56:21PM -0700, Dmitry Torokhov wrote:
> On Wed, Mar 14, 2018 at 08:51:24PM +0000, Nick Dyer wrote:
> > On Mon, Mar 12, 2018 at 12:08:54PM -0700, Dmitry Torokhov wrote:
> > > The way we are supposed to put controller to sleep and wake it up does not
> > > depend on the platform, but rather on controller itself. Controllers using
> > > T9 require manipulating T9 control register, while others, using newer
> > > T100, should be put to sleep by adjusting T7 power config.
> > 
> > I'm afraid this is actually a misconception. If you look at object table
> > for the older T9 device, you'll find it has the T7 object and it in fact
> > works exactly the same way as the T100-based device.
> > 
> > The MXT_SUSPEND_T9_CTRL is in there because on your older Pixel devices
> > the config saved into NVRAM on the touch controller has a zero byte in
> > the T9 CTRL setting, meaning the touch controller will never wake up
> > unless the driver knows to write 0x83 into it.
> 
> Ah, OK, I see. I would really like to drop this pdata->suspend_mode
> stuff and I do not want to create "pixel-screwed-up" property either...
> I guess for the time being I'll put a DMI quirk for Link to restore T9
> control method, and then look into cleaning it all up. We have quite a
> bit different code in chromeos kernel trees and I'd like to reconcile
> it.

Yes, it would be great to get rid of it. The driver does have the
ability to download configuration via the firmware loader interface. So
you would be able to grab a copy of the config by saving it with
mxt-app, tweak it to ensure that the T9 CTRL byte is set correctly, then
ship it somehow (presumably it could be added to linux-firmware). This
would override what's currently stored in NVRAM on all those units and
mean we could remove the T9_CTRL stuff.

I'm happy to talk you through sorting that out in more detail if you
want to give it a go. I don't have any Pixel 1 hardware available at the
moment, unfortunately.

N


Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data

2018-03-16 Thread Nick Dyer
On Thu, Mar 15, 2018 at 04:56:21PM -0700, Dmitry Torokhov wrote:
> On Wed, Mar 14, 2018 at 08:51:24PM +0000, Nick Dyer wrote:
> > On Mon, Mar 12, 2018 at 12:08:54PM -0700, Dmitry Torokhov wrote:
> > > The way we are supposed to put controller to sleep and wake it up does not
> > > depend on the platform, but rather on controller itself. Controllers using
> > > T9 require manipulating T9 control register, while others, using newer
> > > T100, should be put to sleep by adjusting T7 power config.
> > 
> > I'm afraid this is actually a misconception. If you look at object table
> > for the older T9 device, you'll find it has the T7 object and it in fact
> > works exactly the same way as the T100-based device.
> > 
> > The MXT_SUSPEND_T9_CTRL is in there because on your older Pixel devices
> > the config saved into NVRAM on the touch controller has a zero byte in
> > the T9 CTRL setting, meaning the touch controller will never wake up
> > unless the driver knows to write 0x83 into it.
> 
> Ah, OK, I see. I would really like to drop this pdata->suspend_mode
> stuff and I do not want to create "pixel-screwed-up" property either...
> I guess for the time being I'll put a DMI quirk for Link to restore T9
> control method, and then look into cleaning it all up. We have quite a
> bit different code in chromeos kernel trees and I'd like to reconcile
> it.

Yes, it would be great to get rid of it. The driver does have the
ability to download configuration via the firmware loader interface. So
you would be able to grab a copy of the config by saving it with
mxt-app, tweak it to ensure that the T9 CTRL byte is set correctly, then
ship it somehow (presumably it could be added to linux-firmware). This
would override what's currently stored in NVRAM on all those units and
mean we could remove the T9_CTRL stuff.

I'm happy to talk you through sorting that out in more detail if you
want to give it a go. I don't have any Pixel 1 hardware available at the
moment, unfortunately.

N


Re: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support

2018-03-16 Thread Nick Dyer
On Thu, Mar 15, 2018 at 05:06:14PM -0700, Dmitry Torokhov wrote:
> On Wed, Mar 14, 2018 at 08:59:38PM +0000, Nick Dyer wrote:
> > On Mon, Mar 12, 2018 at 12:09:07PM -0700, Dmitry Torokhov wrote:
> > > - /*
> > > -  * Ignore ACPI devices representing bootloader mode.
> > > -  *
> > > -  * This is a bit of a hack: Google Chromebook BIOS creates ACPI
> > > -  * devices for both application and bootloader modes, but we are
> > > -  * interested in application mode only (if device is in bootloader
> > > -  * mode we'll end up switching into application anyway). So far
> > > -  * application mode addresses were all above 0x40, so we'll use it
> > > -  * as a threshold.
> > > -  */
> > > - if (client->addr < 0x40)
> > > - return -ENXIO;
> > 
> > Could you use 0x4a, since that's the lowest application mode address,
> > same in the other place.
> 
> OK, this is existing code though, so I'll make a separate patch.

Ah, I see now. In which case it's no big deal.

Acked-by: Nick Dyer <n...@shmanahar.org>


Re: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support

2018-03-16 Thread Nick Dyer
On Thu, Mar 15, 2018 at 05:06:14PM -0700, Dmitry Torokhov wrote:
> On Wed, Mar 14, 2018 at 08:59:38PM +0000, Nick Dyer wrote:
> > On Mon, Mar 12, 2018 at 12:09:07PM -0700, Dmitry Torokhov wrote:
> > > - /*
> > > -  * Ignore ACPI devices representing bootloader mode.
> > > -  *
> > > -  * This is a bit of a hack: Google Chromebook BIOS creates ACPI
> > > -  * devices for both application and bootloader modes, but we are
> > > -  * interested in application mode only (if device is in bootloader
> > > -  * mode we'll end up switching into application anyway). So far
> > > -  * application mode addresses were all above 0x40, so we'll use it
> > > -  * as a threshold.
> > > -  */
> > > - if (client->addr < 0x40)
> > > - return -ENXIO;
> > 
> > Could you use 0x4a, since that's the lowest application mode address,
> > same in the other place.
> 
> OK, this is existing code though, so I'll make a separate patch.

Ah, I see now. In which case it's no big deal.

Acked-by: Nick Dyer 


Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data

2018-03-14 Thread Nick Dyer
Hi Dmitry-

Thanks for sending these patches!

On Mon, Mar 12, 2018 at 12:08:54PM -0700, Dmitry Torokhov wrote:
> The way we are supposed to put controller to sleep and wake it up does not
> depend on the platform, but rather on controller itself. Controllers using
> T9 require manipulating T9 control register, while others, using newer
> T100, should be put to sleep by adjusting T7 power config.

I'm afraid this is actually a misconception. If you look at object table
for the older T9 device, you'll find it has the T7 object and it in fact
works exactly the same way as the T100-based device.

The MXT_SUSPEND_T9_CTRL is in there because on your older Pixel devices
the config saved into NVRAM on the touch controller has a zero byte in
the T9 CTRL setting, meaning the touch controller will never wake up
unless the driver knows to write 0x83 into it.

> We'll keep pdata->suspend_mode for now and remove it when we rework
> chromeos-laptop driver.
> 
> Signed-off-by: Dmitry Torokhov 
> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc48f1db8..1aabfae1297ba 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -2868,8 +2868,8 @@ static const struct attribute_group mxt_attr_group = {
>  
>  static void mxt_start(struct mxt_data *data)
>  {
> - switch (data->pdata->suspend_mode) {
> - case MXT_SUSPEND_T9_CTRL:
> + switch (data->multitouch) {
> + case MXT_TOUCH_MULTI_T9:
>   mxt_soft_reset(data);
>  
>   /* Touch enable */
> @@ -2878,7 +2878,7 @@ static void mxt_start(struct mxt_data *data)
>   MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83);
>   break;
>  
> - case MXT_SUSPEND_DEEP_SLEEP:
> + case MXT_TOUCH_MULTITOUCHSCREEN_T100:
>   default:
>   mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
>  
> @@ -2886,19 +2886,18 @@ static void mxt_start(struct mxt_data *data)
>   mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
>   break;
>   }
> -
>  }
>  
>  static void mxt_stop(struct mxt_data *data)
>  {
> - switch (data->pdata->suspend_mode) {
> - case MXT_SUSPEND_T9_CTRL:
> + switch (data->multitouch) {
> + case MXT_TOUCH_MULTI_T9:
>   /* Touch disable */
>   mxt_write_object(data,
>   MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0);
>   break;
>  
> - case MXT_SUSPEND_DEEP_SLEEP:
> + case MXT_TOUCH_MULTITOUCHSCREEN_T100:
>   default:
>   mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
>   break;
> @@ -2954,8 +2953,6 @@ static const struct mxt_platform_data 
> *mxt_parse_dt(struct i2c_client *client)
>   pdata->t19_keymap = keymap;
>   }
>  
> - pdata->suspend_mode = MXT_SUSPEND_DEEP_SLEEP;
> -
>   return pdata;
>  }
>  #else
> -- 
> 2.16.2.660.g709887971b-goog
> 


Re: [PATCH 01/14] Input: atmel_mxt_ts - do not pass suspend mode in platform data

2018-03-14 Thread Nick Dyer
Hi Dmitry-

Thanks for sending these patches!

On Mon, Mar 12, 2018 at 12:08:54PM -0700, Dmitry Torokhov wrote:
> The way we are supposed to put controller to sleep and wake it up does not
> depend on the platform, but rather on controller itself. Controllers using
> T9 require manipulating T9 control register, while others, using newer
> T100, should be put to sleep by adjusting T7 power config.

I'm afraid this is actually a misconception. If you look at object table
for the older T9 device, you'll find it has the T7 object and it in fact
works exactly the same way as the T100-based device.

The MXT_SUSPEND_T9_CTRL is in there because on your older Pixel devices
the config saved into NVRAM on the touch controller has a zero byte in
the T9 CTRL setting, meaning the touch controller will never wake up
unless the driver knows to write 0x83 into it.

> We'll keep pdata->suspend_mode for now and remove it when we rework
> chromeos-laptop driver.
> 
> Signed-off-by: Dmitry Torokhov 
> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 15 ++-
>  1 file changed, 6 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc48f1db8..1aabfae1297ba 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -2868,8 +2868,8 @@ static const struct attribute_group mxt_attr_group = {
>  
>  static void mxt_start(struct mxt_data *data)
>  {
> - switch (data->pdata->suspend_mode) {
> - case MXT_SUSPEND_T9_CTRL:
> + switch (data->multitouch) {
> + case MXT_TOUCH_MULTI_T9:
>   mxt_soft_reset(data);
>  
>   /* Touch enable */
> @@ -2878,7 +2878,7 @@ static void mxt_start(struct mxt_data *data)
>   MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0x83);
>   break;
>  
> - case MXT_SUSPEND_DEEP_SLEEP:
> + case MXT_TOUCH_MULTITOUCHSCREEN_T100:
>   default:
>   mxt_set_t7_power_cfg(data, MXT_POWER_CFG_RUN);
>  
> @@ -2886,19 +2886,18 @@ static void mxt_start(struct mxt_data *data)
>   mxt_t6_command(data, MXT_COMMAND_CALIBRATE, 1, false);
>   break;
>   }
> -
>  }
>  
>  static void mxt_stop(struct mxt_data *data)
>  {
> - switch (data->pdata->suspend_mode) {
> - case MXT_SUSPEND_T9_CTRL:
> + switch (data->multitouch) {
> + case MXT_TOUCH_MULTI_T9:
>   /* Touch disable */
>   mxt_write_object(data,
>   MXT_TOUCH_MULTI_T9, MXT_T9_CTRL, 0);
>   break;
>  
> - case MXT_SUSPEND_DEEP_SLEEP:
> + case MXT_TOUCH_MULTITOUCHSCREEN_T100:
>   default:
>   mxt_set_t7_power_cfg(data, MXT_POWER_CFG_DEEPSLEEP);
>   break;
> @@ -2954,8 +2953,6 @@ static const struct mxt_platform_data 
> *mxt_parse_dt(struct i2c_client *client)
>   pdata->t19_keymap = keymap;
>   }
>  
> - pdata->suspend_mode = MXT_SUSPEND_DEEP_SLEEP;
> -
>   return pdata;
>  }
>  #else
> -- 
> 2.16.2.660.g709887971b-goog
> 


Re: [PATCH 03/14] Input: atmel_mxt_ts - switch ChromeOS ACPI devices to generic props

2018-03-14 Thread Nick Dyer
On Mon, Mar 12, 2018 at 12:08:56PM -0700, Dmitry Torokhov wrote:
> Move older ChromeOS devices describing Atmel controllers in ACPI, but not
> providing enough details to configure the controllers properly, from
> platform data over to generic device properties. This will allow us
> remove support for platform data later on, leaving only generic device
> properties in place.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torok...@gmail.com>

Acked-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 63 +++-
>  1 file changed, 40 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 072b78d3c6e00..cf2aac4e79ae8 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -2972,7 +2972,7 @@ mxt_parse_device_properties(struct i2c_client *client)
>  
>  struct mxt_acpi_platform_data {
>   const char *hid;
> - struct mxt_platform_data pdata;
> + const struct property_entry *props;
>  };
>  
>  static unsigned int samus_touchpad_buttons[] = {
> @@ -2982,14 +2982,16 @@ static unsigned int samus_touchpad_buttons[] = {
>   BTN_LEFT
>  };
>  
> +static const struct property_entry samus_touchpad_props[] = {
> + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", samus_touchpad_buttons),
> + { }
> +};
> +
>  static struct mxt_acpi_platform_data samus_platform_data[] = {
>   {
>   /* Touchpad */
>   .hid= "ATML",
> - .pdata  = {
> - .t19_num_keys   = ARRAY_SIZE(samus_touchpad_buttons),
> - .t19_keymap = samus_touchpad_buttons,
> - },
> + .props  = samus_touchpad_props,
>   },
>   {
>   /* Touchscreen */
> @@ -3007,14 +3009,16 @@ static unsigned int chromebook_tp_buttons[] = {
>   BTN_LEFT
>  };
>  
> +static const struct property_entry chromebook_tp_props[] = {
> + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_tp_buttons),
> + { }
> +};
> +
>  static struct mxt_acpi_platform_data chromebook_platform_data[] = {
>   {
>   /* Touchpad */
>   .hid= "ATML",
> - .pdata  = {
> - .t19_num_keys   = ARRAY_SIZE(chromebook_tp_buttons),
> - .t19_keymap = chromebook_tp_buttons,
> - },
> + .props  = chromebook_tp_props,
>   },
>   {
>   /* Touchscreen */
> @@ -3044,7 +3048,7 @@ static const struct dmi_system_id mxt_dmi_table[] = {
>   { }
>  };
>  
> -static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client 
> *client)
> +static int mxt_acpi_probe(struct i2c_client *client)
>  {
>   struct acpi_device *adev;
>   const struct dmi_system_id *system_id;
> @@ -3061,33 +3065,46 @@ static const struct mxt_platform_data 
> *mxt_parse_acpi(struct i2c_client *client)
>* as a threshold.
>*/
>   if (client->addr < 0x40)
> - return ERR_PTR(-ENXIO);
> + return -ENXIO;
>  
>   adev = ACPI_COMPANION(>dev);
>   if (!adev)
> - return ERR_PTR(-ENOENT);
> + return -ENOENT;
>  
>   system_id = dmi_first_match(mxt_dmi_table);
>   if (!system_id)
> - return ERR_PTR(-ENOENT);
> + return -ENOENT;
>  
>   acpi_pdata = system_id->driver_data;
>   if (!acpi_pdata)
> - return ERR_PTR(-ENOENT);
> + return -ENOENT;
>  
>   while (acpi_pdata->hid) {
> - if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid))
> - return _pdata->pdata;
> + if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid)) {
> + /*
> +  * Remove previously installed properties if we
> +  * are probing this device not for the very first
> +  * time.
> +  */
> + device_remove_properties(>dev);
> +
> + /*
> +  * Now install the platform-specific properties
> +  * that are missing from ACPI.
> +  */
> + device_add_properties(>dev, acpi_pdata->props);
> + break;
> + }
>  
>   acpi_pdata++;
>   }
>  
> - return ERR_PTR(-ENOENT);
> + return 0;
>  }
>  #else
> -static 

Re: [PATCH 03/14] Input: atmel_mxt_ts - switch ChromeOS ACPI devices to generic props

2018-03-14 Thread Nick Dyer
On Mon, Mar 12, 2018 at 12:08:56PM -0700, Dmitry Torokhov wrote:
> Move older ChromeOS devices describing Atmel controllers in ACPI, but not
> providing enough details to configure the controllers properly, from
> platform data over to generic device properties. This will allow us
> remove support for platform data later on, leaving only generic device
> properties in place.
> 
> Signed-off-by: Dmitry Torokhov 

Acked-by: Nick Dyer 

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 63 +++-
>  1 file changed, 40 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 072b78d3c6e00..cf2aac4e79ae8 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -2972,7 +2972,7 @@ mxt_parse_device_properties(struct i2c_client *client)
>  
>  struct mxt_acpi_platform_data {
>   const char *hid;
> - struct mxt_platform_data pdata;
> + const struct property_entry *props;
>  };
>  
>  static unsigned int samus_touchpad_buttons[] = {
> @@ -2982,14 +2982,16 @@ static unsigned int samus_touchpad_buttons[] = {
>   BTN_LEFT
>  };
>  
> +static const struct property_entry samus_touchpad_props[] = {
> + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", samus_touchpad_buttons),
> + { }
> +};
> +
>  static struct mxt_acpi_platform_data samus_platform_data[] = {
>   {
>   /* Touchpad */
>   .hid= "ATML",
> - .pdata  = {
> - .t19_num_keys   = ARRAY_SIZE(samus_touchpad_buttons),
> - .t19_keymap = samus_touchpad_buttons,
> - },
> + .props  = samus_touchpad_props,
>   },
>   {
>   /* Touchscreen */
> @@ -3007,14 +3009,16 @@ static unsigned int chromebook_tp_buttons[] = {
>   BTN_LEFT
>  };
>  
> +static const struct property_entry chromebook_tp_props[] = {
> + PROPERTY_ENTRY_U32_ARRAY("linux,gpio-keymap", chromebook_tp_buttons),
> + { }
> +};
> +
>  static struct mxt_acpi_platform_data chromebook_platform_data[] = {
>   {
>   /* Touchpad */
>   .hid= "ATML",
> - .pdata  = {
> - .t19_num_keys   = ARRAY_SIZE(chromebook_tp_buttons),
> - .t19_keymap = chromebook_tp_buttons,
> - },
> + .props  = chromebook_tp_props,
>   },
>   {
>   /* Touchscreen */
> @@ -3044,7 +3048,7 @@ static const struct dmi_system_id mxt_dmi_table[] = {
>   { }
>  };
>  
> -static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_client 
> *client)
> +static int mxt_acpi_probe(struct i2c_client *client)
>  {
>   struct acpi_device *adev;
>   const struct dmi_system_id *system_id;
> @@ -3061,33 +3065,46 @@ static const struct mxt_platform_data 
> *mxt_parse_acpi(struct i2c_client *client)
>* as a threshold.
>*/
>   if (client->addr < 0x40)
> - return ERR_PTR(-ENXIO);
> + return -ENXIO;
>  
>   adev = ACPI_COMPANION(>dev);
>   if (!adev)
> - return ERR_PTR(-ENOENT);
> + return -ENOENT;
>  
>   system_id = dmi_first_match(mxt_dmi_table);
>   if (!system_id)
> - return ERR_PTR(-ENOENT);
> + return -ENOENT;
>  
>   acpi_pdata = system_id->driver_data;
>   if (!acpi_pdata)
> - return ERR_PTR(-ENOENT);
> + return -ENOENT;
>  
>   while (acpi_pdata->hid) {
> - if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid))
> - return _pdata->pdata;
> + if (!strcmp(acpi_device_hid(adev), acpi_pdata->hid)) {
> + /*
> +  * Remove previously installed properties if we
> +  * are probing this device not for the very first
> +  * time.
> +  */
> + device_remove_properties(>dev);
> +
> + /*
> +  * Now install the platform-specific properties
> +  * that are missing from ACPI.
> +  */
> + device_add_properties(>dev, acpi_pdata->props);
> + break;
> + }
>  
>   acpi_pdata++;
>   }
>  
> - return ERR_PTR(-ENOENT);
> + return 0;
>  }
>  #else
> -static const struct mxt_platform_data *mxt_parse_acpi(struct i2c_cl

Re: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support

2018-03-14 Thread Nick Dyer
On Mon, Mar 12, 2018 at 12:09:07PM -0700, Dmitry Torokhov wrote:
> Date: Mon, 12 Mar 2018 12:09:07 -0700
> From: Dmitry Torokhov <dmitry.torok...@gmail.com>
> To: linux-in...@vger.kernel.org, Benson Leung <ble...@chromium.org>
> Cc: Nick Dyer <n...@shmanahar.org>, Olof Johansson <o...@lixom.net>,
>  linux-kernel@vger.kernel.org
> Subject: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support
> 
> Now that there are no users of custom Atmel platform data, and everyone
> has switched to the generic device properties, we can remove support for
> the platform data.

Thanks, this is a nice tidy up.

> Signed-off-by: Dmitry Torokhov <dmitry.torok...@gmail.com>
> ---
>  MAINTAINERS|   1 -
>  drivers/input/touchscreen/atmel_mxt_ts.c   | 125 +
>  include/linux/platform_data/atmel_mxt_ts.h |  31 -
>  3 files changed, 50 insertions(+), 107 deletions(-)
>  delete mode 100644 include/linux/platform_data/atmel_mxt_ts.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4623caf8d72d8..37b70874a4771 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2394,7 +2394,6 @@ T:  git git://github.com/ndyer/linux.git
>  S:   Maintained
>  F:   Documentation/devicetree/bindings/input/atmel,maxtouch.txt
>  F:   drivers/input/touchscreen/atmel_mxt_ts.c
> -F:   include/linux/platform_data/atmel_mxt_ts.h
>  
>  ATMEL SAMA5D2 ADC DRIVER
>  M:   Ludovic Desroches <ludovic.desroc...@microchip.com>
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index cf2aac4e79ae8..642211254acc4 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -23,10 +23,10 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -274,7 +274,6 @@ struct mxt_data {
>   struct i2c_client *client;
>   struct input_dev *input_dev;
>   char phys[64];  /* device physical location */
> - const struct mxt_platform_data *pdata;
>   struct mxt_object *object_table;
>   struct mxt_info info;
>   unsigned int irq;
> @@ -325,6 +324,9 @@ struct mxt_data {
>  
>   /* for config update handling */
>   struct completion crc_completion;
> +
> + u32 *t19_keymap;
> + unsigned int t19_num_keys;
>  };
>  
>  struct mxt_vb2_buffer {
> @@ -743,15 +745,14 @@ static int mxt_write_object(struct mxt_data *data,
>  static void mxt_input_button(struct mxt_data *data, u8 *message)
>  {
>   struct input_dev *input = data->input_dev;
> - const struct mxt_platform_data *pdata = data->pdata;
>   int i;
>  
> - for (i = 0; i < pdata->t19_num_keys; i++) {
> - if (pdata->t19_keymap[i] == KEY_RESERVED)
> + for (i = 0; i < data->t19_num_keys; i++) {
> + if (data->t19_keymap[i] == KEY_RESERVED)
>   continue;
>  
>   /* Active-low switch */
> - input_report_key(input, pdata->t19_keymap[i],
> + input_report_key(input, data->t19_keymap[i],
>!(message[1] & BIT(i)));
>   }
>  }
> @@ -759,7 +760,7 @@ static void mxt_input_button(struct mxt_data *data, u8 
> *message)
>  static void mxt_input_sync(struct mxt_data *data)
>  {
>   input_mt_report_pointer_emulation(data->input_dev,
> -   data->pdata->t19_num_keys);
> +   data->t19_num_keys);
>   input_sync(data->input_dev);
>  }
>  
> @@ -1859,7 +1860,6 @@ static void mxt_input_close(struct input_dev *dev);
>  static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
>  struct mxt_data *data)
>  {
> - const struct mxt_platform_data *pdata = data->pdata;
>   int i;
>  
>   input_dev->name = "Atmel maXTouch Touchpad";
> @@ -1873,15 +1873,14 @@ static void mxt_set_up_as_touchpad(struct input_dev 
> *input_dev,
>   input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
> MXT_PIXELS_PER_MM);
>  
> - for (i = 0; i < pdata->t19_num_keys; i++)
> - if (pdata->t19_keymap[i] != KEY_RESERVED)
> + for (i = 0; i < data->t19_num_keys; i++)
> + if (data->t19_keymap[i] != KEY_RESERVED)
>   input_set_capability(input_dev, EV_KEY,
> -  pdata->t19_keymap[i]);
> +  data->t19_keymap[i]);
>

Re: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support

2018-03-14 Thread Nick Dyer
On Mon, Mar 12, 2018 at 12:09:07PM -0700, Dmitry Torokhov wrote:
> Date: Mon, 12 Mar 2018 12:09:07 -0700
> From: Dmitry Torokhov 
> To: linux-in...@vger.kernel.org, Benson Leung 
> Cc: Nick Dyer , Olof Johansson ,
>  linux-kernel@vger.kernel.org
> Subject: [PATCH 14/14] Input: atmel_mxt_ts - remove platform data support
> 
> Now that there are no users of custom Atmel platform data, and everyone
> has switched to the generic device properties, we can remove support for
> the platform data.

Thanks, this is a nice tidy up.

> Signed-off-by: Dmitry Torokhov 
> ---
>  MAINTAINERS|   1 -
>  drivers/input/touchscreen/atmel_mxt_ts.c   | 125 +
>  include/linux/platform_data/atmel_mxt_ts.h |  31 -
>  3 files changed, 50 insertions(+), 107 deletions(-)
>  delete mode 100644 include/linux/platform_data/atmel_mxt_ts.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4623caf8d72d8..37b70874a4771 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -2394,7 +2394,6 @@ T:  git git://github.com/ndyer/linux.git
>  S:   Maintained
>  F:   Documentation/devicetree/bindings/input/atmel,maxtouch.txt
>  F:   drivers/input/touchscreen/atmel_mxt_ts.c
> -F:   include/linux/platform_data/atmel_mxt_ts.h
>  
>  ATMEL SAMA5D2 ADC DRIVER
>  M:   Ludovic Desroches 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index cf2aac4e79ae8..642211254acc4 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -23,10 +23,10 @@
>  #include 
>  #include 
>  #include 
> -#include 
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -274,7 +274,6 @@ struct mxt_data {
>   struct i2c_client *client;
>   struct input_dev *input_dev;
>   char phys[64];  /* device physical location */
> - const struct mxt_platform_data *pdata;
>   struct mxt_object *object_table;
>   struct mxt_info info;
>   unsigned int irq;
> @@ -325,6 +324,9 @@ struct mxt_data {
>  
>   /* for config update handling */
>   struct completion crc_completion;
> +
> + u32 *t19_keymap;
> + unsigned int t19_num_keys;
>  };
>  
>  struct mxt_vb2_buffer {
> @@ -743,15 +745,14 @@ static int mxt_write_object(struct mxt_data *data,
>  static void mxt_input_button(struct mxt_data *data, u8 *message)
>  {
>   struct input_dev *input = data->input_dev;
> - const struct mxt_platform_data *pdata = data->pdata;
>   int i;
>  
> - for (i = 0; i < pdata->t19_num_keys; i++) {
> - if (pdata->t19_keymap[i] == KEY_RESERVED)
> + for (i = 0; i < data->t19_num_keys; i++) {
> + if (data->t19_keymap[i] == KEY_RESERVED)
>   continue;
>  
>   /* Active-low switch */
> - input_report_key(input, pdata->t19_keymap[i],
> + input_report_key(input, data->t19_keymap[i],
>!(message[1] & BIT(i)));
>   }
>  }
> @@ -759,7 +760,7 @@ static void mxt_input_button(struct mxt_data *data, u8 
> *message)
>  static void mxt_input_sync(struct mxt_data *data)
>  {
>   input_mt_report_pointer_emulation(data->input_dev,
> -   data->pdata->t19_num_keys);
> +   data->t19_num_keys);
>   input_sync(data->input_dev);
>  }
>  
> @@ -1859,7 +1860,6 @@ static void mxt_input_close(struct input_dev *dev);
>  static void mxt_set_up_as_touchpad(struct input_dev *input_dev,
>  struct mxt_data *data)
>  {
> - const struct mxt_platform_data *pdata = data->pdata;
>   int i;
>  
>   input_dev->name = "Atmel maXTouch Touchpad";
> @@ -1873,15 +1873,14 @@ static void mxt_set_up_as_touchpad(struct input_dev 
> *input_dev,
>   input_abs_set_res(input_dev, ABS_MT_POSITION_Y,
> MXT_PIXELS_PER_MM);
>  
> - for (i = 0; i < pdata->t19_num_keys; i++)
> - if (pdata->t19_keymap[i] != KEY_RESERVED)
> + for (i = 0; i < data->t19_num_keys; i++)
> + if (data->t19_keymap[i] != KEY_RESERVED)
>   input_set_capability(input_dev, EV_KEY,
> -  pdata->t19_keymap[i]);
> +  data->t19_keymap[i]);
>  }
>  
>  static int mxt_initialize_input_device(struct mxt_data *data)
>  {
> - const struct mxt_platform_data *pdata = data->pdata;
>   struct device *d

Re: [PATCH 02/14] Input: atmel_mxt_ts - switch from OF to generic device properties

2018-03-14 Thread Nick Dyer
On Mon, Mar 12, 2018 at 12:08:55PM -0700, Dmitry Torokhov wrote:
> Instead of using OF-specific APIs to fecth device properties, let's switch
> to generic device properties API. This will allow us to use device
> properties on legacy ChromeOS devices and get rid of platform data down
> the road.
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torok...@gmail.com>

Acked-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 59 
>  1 file changed, 30 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 1aabfae1297ba..072b78d3c6e00 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -2920,47 +2921,52 @@ static void mxt_input_close(struct input_dev *dev)
>   mxt_stop(data);
>  }
>  
> -#ifdef CONFIG_OF
> -static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client 
> *client)
> +static const struct mxt_platform_data *
> +mxt_parse_device_properties(struct i2c_client *client)
>  {
> + static const char keymap_property[] = "linux,gpio-keymap";
>   struct mxt_platform_data *pdata;
> - struct device_node *np = client->dev.of_node;
>   u32 *keymap;
> - int proplen, ret;
> -
> - if (!np)
> - return ERR_PTR(-ENOENT);
> + int n_keys;
> + int error;
>  
>   pdata = devm_kzalloc(>dev, sizeof(*pdata), GFP_KERNEL);
>   if (!pdata)
>   return ERR_PTR(-ENOMEM);
>  
> - if (of_find_property(np, "linux,gpio-keymap", )) {
> - pdata->t19_num_keys = proplen / sizeof(u32);
> + if (device_property_present(>dev, keymap_property)) {
> + n_keys = device_property_read_u32_array(>dev,
> + keymap_property,
> + NULL, 0);
> + if (n_keys <= 0) {
> + error = n_keys < 0 ? n_keys : -EINVAL;
> + dev_err(>dev,
> + "invalid/malformed '%s' property: %d\n",
> + keymap_property, error);
> + return ERR_PTR(error);
> + }
>  
> - keymap = devm_kzalloc(>dev,
> - pdata->t19_num_keys * sizeof(keymap[0]),
> - GFP_KERNEL);
> + keymap = devm_kmalloc_array(>dev, n_keys, sizeof(u32),
> + GFP_KERNEL);
>   if (!keymap)
>   return ERR_PTR(-ENOMEM);
>  
> - ret = of_property_read_u32_array(np, "linux,gpio-keymap",
> -  keymap, pdata->t19_num_keys);
> - if (ret)
> - dev_warn(>dev,
> -  "Couldn't read linux,gpio-keymap: %d\n", ret);
> + error = device_property_read_u32_array(>dev,
> +keymap_property,
> +keymap, n_keys);
> + if (error) {
> + dev_err(>dev,
> + "failed to parse '%s' property: %d\n",
> + keymap_property, error);
> + return ERR_PTR(error);
> + }
>  
>   pdata->t19_keymap = keymap;
> + pdata->t19_num_keys = n_keys;
>   }
>  
>   return pdata;
>  }
> -#else
> -static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client 
> *client)
> -{
> - return ERR_PTR(-ENOENT);
> -}
> -#endif
>  
>  #ifdef CONFIG_ACPI
>  
> @@ -3094,16 +3100,11 @@ mxt_get_platform_data(struct i2c_client *client)
>   if (pdata)
>   return pdata;
>  
> - pdata = mxt_parse_dt(client);
> - if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
> - return pdata;
> -
>   pdata = mxt_parse_acpi(client);
>   if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
>   return pdata;
>  
> - dev_err(>dev, "No platform data specified\n");
> - return ERR_PTR(-EINVAL);
> + return mxt_parse_device_properties(client);
>  }
>  
>  static int mxt_probe(struct i2c_client *client, const struct i2c_device_id 
> *id)
> -- 
> 2.16.2.660.g709887971b-goog
> 


Re: [PATCH 02/14] Input: atmel_mxt_ts - switch from OF to generic device properties

2018-03-14 Thread Nick Dyer
On Mon, Mar 12, 2018 at 12:08:55PM -0700, Dmitry Torokhov wrote:
> Instead of using OF-specific APIs to fecth device properties, let's switch
> to generic device properties API. This will allow us to use device
> properties on legacy ChromeOS devices and get rid of platform data down
> the road.
> 
> Signed-off-by: Dmitry Torokhov 

Acked-by: Nick Dyer 

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 59 
>  1 file changed, 30 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 1aabfae1297ba..072b78d3c6e00 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -2920,47 +2921,52 @@ static void mxt_input_close(struct input_dev *dev)
>   mxt_stop(data);
>  }
>  
> -#ifdef CONFIG_OF
> -static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client 
> *client)
> +static const struct mxt_platform_data *
> +mxt_parse_device_properties(struct i2c_client *client)
>  {
> + static const char keymap_property[] = "linux,gpio-keymap";
>   struct mxt_platform_data *pdata;
> - struct device_node *np = client->dev.of_node;
>   u32 *keymap;
> - int proplen, ret;
> -
> - if (!np)
> - return ERR_PTR(-ENOENT);
> + int n_keys;
> + int error;
>  
>   pdata = devm_kzalloc(>dev, sizeof(*pdata), GFP_KERNEL);
>   if (!pdata)
>   return ERR_PTR(-ENOMEM);
>  
> - if (of_find_property(np, "linux,gpio-keymap", )) {
> - pdata->t19_num_keys = proplen / sizeof(u32);
> + if (device_property_present(>dev, keymap_property)) {
> + n_keys = device_property_read_u32_array(>dev,
> + keymap_property,
> + NULL, 0);
> + if (n_keys <= 0) {
> + error = n_keys < 0 ? n_keys : -EINVAL;
> + dev_err(>dev,
> + "invalid/malformed '%s' property: %d\n",
> + keymap_property, error);
> + return ERR_PTR(error);
> + }
>  
> - keymap = devm_kzalloc(>dev,
> - pdata->t19_num_keys * sizeof(keymap[0]),
> - GFP_KERNEL);
> + keymap = devm_kmalloc_array(>dev, n_keys, sizeof(u32),
> + GFP_KERNEL);
>   if (!keymap)
>   return ERR_PTR(-ENOMEM);
>  
> - ret = of_property_read_u32_array(np, "linux,gpio-keymap",
> -  keymap, pdata->t19_num_keys);
> - if (ret)
> - dev_warn(>dev,
> -  "Couldn't read linux,gpio-keymap: %d\n", ret);
> + error = device_property_read_u32_array(>dev,
> +keymap_property,
> +keymap, n_keys);
> + if (error) {
> + dev_err(>dev,
> + "failed to parse '%s' property: %d\n",
> + keymap_property, error);
> + return ERR_PTR(error);
> + }
>  
>   pdata->t19_keymap = keymap;
> + pdata->t19_num_keys = n_keys;
>   }
>  
>   return pdata;
>  }
> -#else
> -static const struct mxt_platform_data *mxt_parse_dt(struct i2c_client 
> *client)
> -{
> - return ERR_PTR(-ENOENT);
> -}
> -#endif
>  
>  #ifdef CONFIG_ACPI
>  
> @@ -3094,16 +3100,11 @@ mxt_get_platform_data(struct i2c_client *client)
>   if (pdata)
>   return pdata;
>  
> - pdata = mxt_parse_dt(client);
> - if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
> - return pdata;
> -
>   pdata = mxt_parse_acpi(client);
>   if (!IS_ERR(pdata) || PTR_ERR(pdata) != -ENOENT)
>   return pdata;
>  
> - dev_err(>dev, "No platform data specified\n");
> - return ERR_PTR(-EINVAL);
> + return mxt_parse_device_properties(client);
>  }
>  
>  static int mxt_probe(struct i2c_client *client, const struct i2c_device_id 
> *id)
> -- 
> 2.16.2.660.g709887971b-goog
> 


Re: [PATCH] input/rmi4: Delete an error message for a failed memory allocation in two functions

2018-01-24 Thread Nick Dyer
On Wed, Jan 24, 2018 at 07:28:44PM +0100, SF Markus Elfring wrote:
> Omit an extra message for a memory allocation failure in these functions.
> 
> This issue was detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring <elfr...@users.sourceforge.net>

Signed-off-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/rmi4/rmi_driver.c | 4 +---
>  drivers/input/rmi4/rmi_f30.c| 4 +---
>  2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index 4f2bb5947a4e..6c47e4f3ca7e 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -1060,10 +1060,8 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
>  
>   size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long);
>   data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL);
> - if (!data->irq_memory) {
> - dev_err(dev, "Failed to allocate memory for irq masks.\n");
> + if (!data->irq_memory)
>   return -ENOMEM;
> - }
>  
>   data->irq_status= data->irq_memory + size * 0;
>   data->fn_irq_bits   = data->irq_memory + size * 1;
> diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
> index 82e0f0d43d55..a111ea370c30 100644
> --- a/drivers/input/rmi4/rmi_f30.c
> +++ b/drivers/input/rmi4/rmi_f30.c
> @@ -238,10 +238,8 @@ static int rmi_f30_map_gpios(struct rmi_function *fn,
>   button_count,
>   sizeof(f30->gpioled_key_map[0]),
>   GFP_KERNEL);
> - if (!f30->gpioled_key_map) {
> - dev_err(>dev, "Failed to allocate gpioled map memory.\n");
> + if (!f30->gpioled_key_map)
>   return -ENOMEM;
> - }
>  
>   for (i = 0; i < button_count; i++) {
>   if (!rmi_f30_is_valid_button(i, f30->ctrl))
> -- 
> 2.16.1
> 


Re: [PATCH] input/rmi4: Delete an error message for a failed memory allocation in two functions

2018-01-24 Thread Nick Dyer
On Wed, Jan 24, 2018 at 07:28:44PM +0100, SF Markus Elfring wrote:
> Omit an extra message for a memory allocation failure in these functions.
> 
> This issue was detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring 

Signed-off-by: Nick Dyer 

> ---
>  drivers/input/rmi4/rmi_driver.c | 4 +---
>  drivers/input/rmi4/rmi_f30.c| 4 +---
>  2 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index 4f2bb5947a4e..6c47e4f3ca7e 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -1060,10 +1060,8 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
>  
>   size = BITS_TO_LONGS(data->irq_count) * sizeof(unsigned long);
>   data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL);
> - if (!data->irq_memory) {
> - dev_err(dev, "Failed to allocate memory for irq masks.\n");
> + if (!data->irq_memory)
>   return -ENOMEM;
> - }
>  
>   data->irq_status= data->irq_memory + size * 0;
>   data->fn_irq_bits   = data->irq_memory + size * 1;
> diff --git a/drivers/input/rmi4/rmi_f30.c b/drivers/input/rmi4/rmi_f30.c
> index 82e0f0d43d55..a111ea370c30 100644
> --- a/drivers/input/rmi4/rmi_f30.c
> +++ b/drivers/input/rmi4/rmi_f30.c
> @@ -238,10 +238,8 @@ static int rmi_f30_map_gpios(struct rmi_function *fn,
>   button_count,
>   sizeof(f30->gpioled_key_map[0]),
>   GFP_KERNEL);
> - if (!f30->gpioled_key_map) {
> - dev_err(>dev, "Failed to allocate gpioled map memory.\n");
> + if (!f30->gpioled_key_map)
>   return -ENOMEM;
> - }
>  
>   for (i = 0; i < button_count; i++) {
>   if (!rmi_f30_is_valid_button(i, f30->ctrl))
> -- 
> 2.16.1
> 


Re: [PATCH] Input: atmel_mxt_ts: Delete error messages for a failed memory allocation in two functions

2018-01-24 Thread Nick Dyer
On Sun, Jan 21, 2018 at 10:33:50PM +0100, SF Markus Elfring wrote:
> Omit extra messages for a memory allocation failure in these functions.
> 
> This issue was detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring <elfr...@users.sourceforge.net>

Thanks!

Signed-off-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 9 ++---
>  1 file changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc48f1db..f38711e9c256 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -1507,10 +1507,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
> struct firmware *cfg)
>   MXT_INFO_CHECKSUM_SIZE;
>   config_mem_size = data->mem_size - cfg_start_ofs;
>   config_mem = kzalloc(config_mem_size, GFP_KERNEL);
> - if (!config_mem) {
> - dev_err(dev, "Failed to allocate memory\n");
> + if (!config_mem)
>   return -ENOMEM;
> - }
>  
>   ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs,
> config_mem, config_mem_size);
> @@ -1612,10 +1610,8 @@ static int mxt_get_object_table(struct mxt_data *data)
>  
>   table_size = data->info.object_num * sizeof(struct mxt_object);
>   object_table = kzalloc(table_size, GFP_KERNEL);
> - if (!object_table) {
> - dev_err(>client->dev, "Failed to allocate memory\n");
> + if (!object_table)
>   return -ENOMEM;
> - }
>  
>   error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
>   object_table);
> @@ -1714,7 +1710,6 @@ static int mxt_get_object_table(struct mxt_data *data)
>   data->msg_buf = kcalloc(data->max_reportid,
>   data->T5_msg_size, GFP_KERNEL);
>   if (!data->msg_buf) {
> - dev_err(>dev, "Failed to allocate message buffer\n");
>   error = -ENOMEM;
>   goto free_object_table;
>   }
> -- 
> 2.16.0
> 


Re: [PATCH] Input: atmel_mxt_ts: Delete error messages for a failed memory allocation in two functions

2018-01-24 Thread Nick Dyer
On Sun, Jan 21, 2018 at 10:33:50PM +0100, SF Markus Elfring wrote:
> Omit extra messages for a memory allocation failure in these functions.
> 
> This issue was detected by using the Coccinelle software.
> 
> Signed-off-by: Markus Elfring 

Thanks!

Signed-off-by: Nick Dyer 

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 9 ++---
>  1 file changed, 2 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc48f1db..f38711e9c256 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -1507,10 +1507,8 @@ static int mxt_update_cfg(struct mxt_data *data, const 
> struct firmware *cfg)
>   MXT_INFO_CHECKSUM_SIZE;
>   config_mem_size = data->mem_size - cfg_start_ofs;
>   config_mem = kzalloc(config_mem_size, GFP_KERNEL);
> - if (!config_mem) {
> - dev_err(dev, "Failed to allocate memory\n");
> + if (!config_mem)
>   return -ENOMEM;
> - }
>  
>   ret = mxt_prepare_cfg_mem(data, cfg, data_pos, cfg_start_ofs,
> config_mem, config_mem_size);
> @@ -1612,10 +1610,8 @@ static int mxt_get_object_table(struct mxt_data *data)
>  
>   table_size = data->info.object_num * sizeof(struct mxt_object);
>   object_table = kzalloc(table_size, GFP_KERNEL);
> - if (!object_table) {
> - dev_err(>client->dev, "Failed to allocate memory\n");
> + if (!object_table)
>   return -ENOMEM;
> - }
>  
>   error = __mxt_read_reg(client, MXT_OBJECT_START, table_size,
>   object_table);
> @@ -1714,7 +1710,6 @@ static int mxt_get_object_table(struct mxt_data *data)
>   data->msg_buf = kcalloc(data->max_reportid,
>   data->T5_msg_size, GFP_KERNEL);
>   if (!data->msg_buf) {
> - dev_err(>dev, "Failed to allocate message buffer\n");
>   error = -ENOMEM;
>   goto free_object_table;
>   }
> -- 
> 2.16.0
> 


Re: [PATCH] input: atmel_mxt_ts: detect touchpad from devicetree

2017-10-08 Thread Nick Dyer
On Wed, Oct 04, 2017 at 09:35:31PM +0200, Emil Renner Berthing wrote:
> The Samsung Chromebook Plus (rk3399-gru-kevin) has two of
> these controllers. One for the touchscreen and one for
> the touchpad. However the touchpad doesn't have any
> associated gpio buttons, so it shows up as another
> touchscreen.
> 
> This patch fixes it by matching the "atmel,atmel_mxt_tp"
> compatibility string in the device tree.

Thanks. I think this makes sense, given there are already devices out
there using "atmel_mxt_tp".

Is the hardcoded MXT_PIXELS_PER_MM going to cause issues on this new
device?

I think you need to add this to
Documentation/devicetree/bindings/input/atmel,maxtouch.txt

Reviewed-by: Nick Dyer <n...@shmanahar.org>

> Signed-off-by: Emil Renner Berthing <ker...@esmil.dk>
> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c   | 8 ++--
>  include/linux/platform_data/atmel_mxt_ts.h | 1 +
>  2 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc48f1db..4ea06f447d15 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -1945,8 +1945,7 @@ static int mxt_initialize_input_device(struct mxt_data 
> *data)
>   input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
>   }
>  
> - /* If device has buttons we assume it is a touchpad */
> - if (pdata->t19_num_keys) {
> + if (pdata->touchpad) {
>   mxt_set_up_as_touchpad(input_dev, data);
>   mt_flags |= INPUT_MT_POINTER;
>   } else {
> @@ -2936,6 +2935,9 @@ static const struct mxt_platform_data 
> *mxt_parse_dt(struct i2c_client *client)
>   if (!pdata)
>   return ERR_PTR(-ENOMEM);
>  
> + if (of_device_is_compatible(np, "atmel,atmel_mxt_tp"))
> + pdata->touchpad = true;
> +
>   if (of_find_property(np, "linux,gpio-keymap", )) {
>   pdata->t19_num_keys = proplen / sizeof(u32);
>  
> @@ -2986,6 +2988,7 @@ static struct mxt_acpi_platform_data 
> samus_platform_data[] = {
>   .pdata  = {
>   .t19_num_keys   = ARRAY_SIZE(samus_touchpad_buttons),
>   .t19_keymap = samus_touchpad_buttons,
> + .touchpad   = true,
>   },
>   },
>   {
> @@ -3011,6 +3014,7 @@ static struct mxt_acpi_platform_data 
> chromebook_platform_data[] = {
>   .pdata  = {
>   .t19_num_keys   = ARRAY_SIZE(chromebook_tp_buttons),
>   .t19_keymap = chromebook_tp_buttons,
> + .touchpad   = true,
>   },
>   },
>   {
> diff --git a/include/linux/platform_data/atmel_mxt_ts.h 
> b/include/linux/platform_data/atmel_mxt_ts.h
> index 695035a8d7fb..acb595bba02d 100644
> --- a/include/linux/platform_data/atmel_mxt_ts.h
> +++ b/include/linux/platform_data/atmel_mxt_ts.h
> @@ -24,6 +24,7 @@ enum mxt_suspend_mode {
>  struct mxt_platform_data {
>   unsigned long irqflags;
>   u8 t19_num_keys;
> + u8 touchpad;
>   const unsigned int *t19_keymap;
>   enum mxt_suspend_mode suspend_mode;
>  };
> -- 
> 2.14.2
> 


Re: [PATCH] input: atmel_mxt_ts: detect touchpad from devicetree

2017-10-08 Thread Nick Dyer
On Wed, Oct 04, 2017 at 09:35:31PM +0200, Emil Renner Berthing wrote:
> The Samsung Chromebook Plus (rk3399-gru-kevin) has two of
> these controllers. One for the touchscreen and one for
> the touchpad. However the touchpad doesn't have any
> associated gpio buttons, so it shows up as another
> touchscreen.
> 
> This patch fixes it by matching the "atmel,atmel_mxt_tp"
> compatibility string in the device tree.

Thanks. I think this makes sense, given there are already devices out
there using "atmel_mxt_tp".

Is the hardcoded MXT_PIXELS_PER_MM going to cause issues on this new
device?

I think you need to add this to
Documentation/devicetree/bindings/input/atmel,maxtouch.txt

Reviewed-by: Nick Dyer 

> Signed-off-by: Emil Renner Berthing 
> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c   | 8 ++--
>  include/linux/platform_data/atmel_mxt_ts.h | 1 +
>  2 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc48f1db..4ea06f447d15 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -1945,8 +1945,7 @@ static int mxt_initialize_input_device(struct mxt_data 
> *data)
>   input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0);
>   }
>  
> - /* If device has buttons we assume it is a touchpad */
> - if (pdata->t19_num_keys) {
> + if (pdata->touchpad) {
>   mxt_set_up_as_touchpad(input_dev, data);
>   mt_flags |= INPUT_MT_POINTER;
>   } else {
> @@ -2936,6 +2935,9 @@ static const struct mxt_platform_data 
> *mxt_parse_dt(struct i2c_client *client)
>   if (!pdata)
>   return ERR_PTR(-ENOMEM);
>  
> + if (of_device_is_compatible(np, "atmel,atmel_mxt_tp"))
> + pdata->touchpad = true;
> +
>   if (of_find_property(np, "linux,gpio-keymap", )) {
>   pdata->t19_num_keys = proplen / sizeof(u32);
>  
> @@ -2986,6 +2988,7 @@ static struct mxt_acpi_platform_data 
> samus_platform_data[] = {
>   .pdata  = {
>   .t19_num_keys   = ARRAY_SIZE(samus_touchpad_buttons),
>   .t19_keymap = samus_touchpad_buttons,
> + .touchpad   = true,
>   },
>   },
>   {
> @@ -3011,6 +3014,7 @@ static struct mxt_acpi_platform_data 
> chromebook_platform_data[] = {
>   .pdata  = {
>   .t19_num_keys   = ARRAY_SIZE(chromebook_tp_buttons),
>   .t19_keymap = chromebook_tp_buttons,
> + .touchpad   = true,
>   },
>   },
>   {
> diff --git a/include/linux/platform_data/atmel_mxt_ts.h 
> b/include/linux/platform_data/atmel_mxt_ts.h
> index 695035a8d7fb..acb595bba02d 100644
> --- a/include/linux/platform_data/atmel_mxt_ts.h
> +++ b/include/linux/platform_data/atmel_mxt_ts.h
> @@ -24,6 +24,7 @@ enum mxt_suspend_mode {
>  struct mxt_platform_data {
>   unsigned long irqflags;
>   u8 t19_num_keys;
> + u8 touchpad;
>   const unsigned int *t19_keymap;
>   enum mxt_suspend_mode suspend_mode;
>  };
> -- 
> 2.14.2
> 


Re: [PATCH] Input: atmel_mxt_ts - Remove unnecessary byte_offset check

2017-10-08 Thread Nick Dyer
On Sun, Oct 08, 2017 at 07:44:18PM +0100, Christos Gkekas wrote:
> Variable byte_offset is unsigned so checking whether it is greater or
> equal to zero is redundant.
> 
> Signed-off-by: Christos Gkekas <chris.ge...@gmail.com>

Yep - looks sensible to me.

Signed-off-by: Nick Dyer <n...@shmanahar.org>

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc4..baafaed 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -1356,7 +1356,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
>  
>   byte_offset = reg + i - cfg_start_ofs;
>  
> - if (byte_offset >= 0 && byte_offset < config_mem_size) {
> + if (byte_offset < config_mem_size) {
>   *(config_mem + byte_offset) = val;
>   } else {
>   dev_err(dev, "Bad object: reg:%d, T%d, 
> ofs=%d\n",
> -- 
> 2.7.4
> 


Re: [PATCH] Input: atmel_mxt_ts - Remove unnecessary byte_offset check

2017-10-08 Thread Nick Dyer
On Sun, Oct 08, 2017 at 07:44:18PM +0100, Christos Gkekas wrote:
> Variable byte_offset is unsigned so checking whether it is greater or
> equal to zero is redundant.
> 
> Signed-off-by: Christos Gkekas 

Yep - looks sensible to me.

Signed-off-by: Nick Dyer 

> ---
>  drivers/input/touchscreen/atmel_mxt_ts.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 7659bc4..baafaed 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -1356,7 +1356,7 @@ static int mxt_prepare_cfg_mem(struct mxt_data *data,
>  
>   byte_offset = reg + i - cfg_start_ofs;
>  
> - if (byte_offset >= 0 && byte_offset < config_mem_size) {
> + if (byte_offset < config_mem_size) {
>   *(config_mem + byte_offset) = val;
>   } else {
>   dev_err(dev, "Bad object: reg:%d, T%d, 
> ofs=%d\n",
> -- 
> 2.7.4
> 


Re: [PATCH] atmel_mxt_ts: Add support for reset line

2017-06-29 Thread Nick Dyer
On Tue, Jun 27, 2017 at 06:24:38PM +0200, Sebastian Reichel wrote:
> At least some of the Atmel Maxtouch touchscreen controllers have a reset
> pin. If this is not driven correctly the device will be held in reset
> and will not respond.
> 
> Add support for driving the reset line via GPIO as is found in other
> such drivers.

Thanks for this useful improvement.

> Signed-off-by: Martyn Welch 
> [add reset cycle during probe, minor style fixes, add DT binding]
> Signed-off-by: Sebastian Reichel 
> ---
>  .../devicetree/bindings/input/atmel,maxtouch.txt   |  2 ++
>  drivers/input/touchscreen/atmel_mxt_ts.c   | 27 
> +-
>  2 files changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt 
> b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> index 1852906517ab..23e3abc3fdef 100644
> --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> @@ -22,6 +22,8 @@ Optional properties for main touchpad device:
>  experiment to determine which bit corresponds to which input. Use
>  KEY_RESERVED for unused padding values.
>  
> +- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
> +
>  Example:
>  
>   touch@4b {
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index dd042a9b0aaa..b84bf973fe36 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -28,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -300,6 +301,7 @@ struct mxt_data {
>   u8 multitouch;
>   struct t7_config t7_cfg;
>   struct mxt_dbg dbg;
> + struct gpio_desc *reset_gpio;
>  
>   /* Cached parameters from object table */
>   u16 T5_address;
> @@ -3135,12 +3137,26 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   init_completion(>reset_completion);
>   init_completion(>crc_completion);
>  
> + data->reset_gpio = gpiod_get_optional(>dev, "reset",
> +   GPIOD_OUT_LOW);

Please could you use the devm_gpiod_get_optional, it reduces the code to
free it later.

> + if (IS_ERR(data->reset_gpio)) {
> + error = PTR_ERR(data->reset_gpio);
> + dev_err(>dev, "Failed to get reset gpio: %d\n", error);
> + goto err_free_mem;
> + }
> +
> + if (data->reset_gpio) {
> + msleep(MXT_RESET_TIME);
> + gpiod_set_value(data->reset_gpio, 1);
> + msleep(MXT_RESET_TIME);
> + }

This is alright, although the time for reset varies between maXTouch
parts. It would be better to wait for the CHG line to go low, for
example see the code at
https://github.com/atmel-maxtouch/linux/blob/for-upstream/drivers/input/touchscreen/atmel_mxt_ts.c#L2237

> +
>   error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
>pdata->irqflags | IRQF_ONESHOT,
>client->name, data);
>   if (error) {
>   dev_err(>dev, "Failed to register interrupt\n");
> - goto err_free_mem;
> + goto err_free_gpio;
>   }
>  
>   disable_irq(client->irq);
> @@ -3163,6 +3179,11 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   mxt_free_object_table(data);
>  err_free_irq:
>   free_irq(client->irq, data);
> +err_free_gpio:
> + if (data->reset_gpio) {
> + gpiod_set_value(data->reset_gpio, 0);
> + gpiod_put(data->reset_gpio);
> + }
>  err_free_mem:
>   kfree(data);
>   return error;
> @@ -3174,6 +3195,10 @@ static int mxt_remove(struct i2c_client *client)
>  
>   sysfs_remove_group(>dev.kobj, _attr_group);
>   free_irq(data->irq, data);
> + if (data->reset_gpio) {
> + gpiod_set_value(data->reset_gpio, 0);
> + gpiod_put(data->reset_gpio);
> + }
>   mxt_free_input_device(data);
>   mxt_free_object_table(data);
>   kfree(data);
> -- 
> 2.11.0
> 


Re: [PATCH] atmel_mxt_ts: Add support for reset line

2017-06-29 Thread Nick Dyer
On Tue, Jun 27, 2017 at 06:24:38PM +0200, Sebastian Reichel wrote:
> At least some of the Atmel Maxtouch touchscreen controllers have a reset
> pin. If this is not driven correctly the device will be held in reset
> and will not respond.
> 
> Add support for driving the reset line via GPIO as is found in other
> such drivers.

Thanks for this useful improvement.

> Signed-off-by: Martyn Welch 
> [add reset cycle during probe, minor style fixes, add DT binding]
> Signed-off-by: Sebastian Reichel 
> ---
>  .../devicetree/bindings/input/atmel,maxtouch.txt   |  2 ++
>  drivers/input/touchscreen/atmel_mxt_ts.c   | 27 
> +-
>  2 files changed, 28 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt 
> b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> index 1852906517ab..23e3abc3fdef 100644
> --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
> @@ -22,6 +22,8 @@ Optional properties for main touchpad device:
>  experiment to determine which bit corresponds to which input. Use
>  KEY_RESERVED for unused padding values.
>  
> +- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
> +
>  Example:
>  
>   touch@4b {
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c 
> b/drivers/input/touchscreen/atmel_mxt_ts.c
> index dd042a9b0aaa..b84bf973fe36 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -28,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -300,6 +301,7 @@ struct mxt_data {
>   u8 multitouch;
>   struct t7_config t7_cfg;
>   struct mxt_dbg dbg;
> + struct gpio_desc *reset_gpio;
>  
>   /* Cached parameters from object table */
>   u16 T5_address;
> @@ -3135,12 +3137,26 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   init_completion(>reset_completion);
>   init_completion(>crc_completion);
>  
> + data->reset_gpio = gpiod_get_optional(>dev, "reset",
> +   GPIOD_OUT_LOW);

Please could you use the devm_gpiod_get_optional, it reduces the code to
free it later.

> + if (IS_ERR(data->reset_gpio)) {
> + error = PTR_ERR(data->reset_gpio);
> + dev_err(>dev, "Failed to get reset gpio: %d\n", error);
> + goto err_free_mem;
> + }
> +
> + if (data->reset_gpio) {
> + msleep(MXT_RESET_TIME);
> + gpiod_set_value(data->reset_gpio, 1);
> + msleep(MXT_RESET_TIME);
> + }

This is alright, although the time for reset varies between maXTouch
parts. It would be better to wait for the CHG line to go low, for
example see the code at
https://github.com/atmel-maxtouch/linux/blob/for-upstream/drivers/input/touchscreen/atmel_mxt_ts.c#L2237

> +
>   error = request_threaded_irq(client->irq, NULL, mxt_interrupt,
>pdata->irqflags | IRQF_ONESHOT,
>client->name, data);
>   if (error) {
>   dev_err(>dev, "Failed to register interrupt\n");
> - goto err_free_mem;
> + goto err_free_gpio;
>   }
>  
>   disable_irq(client->irq);
> @@ -3163,6 +3179,11 @@ static int mxt_probe(struct i2c_client *client, const 
> struct i2c_device_id *id)
>   mxt_free_object_table(data);
>  err_free_irq:
>   free_irq(client->irq, data);
> +err_free_gpio:
> + if (data->reset_gpio) {
> + gpiod_set_value(data->reset_gpio, 0);
> + gpiod_put(data->reset_gpio);
> + }
>  err_free_mem:
>   kfree(data);
>   return error;
> @@ -3174,6 +3195,10 @@ static int mxt_remove(struct i2c_client *client)
>  
>   sysfs_remove_group(>dev.kobj, _attr_group);
>   free_irq(data->irq, data);
> + if (data->reset_gpio) {
> + gpiod_set_value(data->reset_gpio, 0);
> + gpiod_put(data->reset_gpio);
> + }
>   mxt_free_input_device(data);
>   mxt_free_object_table(data);
>   kfree(data);
> -- 
> 2.11.0
> 


Re: [PATCH] Input: synaptics-rmi4 - Only read the F54 query registers which are used

2017-06-22 Thread Nick Dyer
On Tue, Jun 20, 2017 at 04:08:48PM -0700, Andrew Duggan wrote:
> The F54 driver is currently only using the first 6 bytes of F54 so there
> is no need to read all 27 bytes. Some Dell systems
> (Dell XP13 9333 and similar) have an issue with the touchpad or I2C bus
> when readiing reports larger then 16 bytes. Reads larger then 16 bytes
> are reported in two HID reports. Something about the back to back
> reports seems to cause the next read to report incorrect data. This
> results in F30 failing to load and the click button failing to work.
> 
> Previous issues with the I2C controller or touchpad were addressed in:
> commit 5b65c2a02966 ("HID: rmi: check sanity of the incoming report")
> 
> Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=195949
> Signed-off-by: Andrew Duggan <adug...@synaptics.com>

Looks fine to me.

Reviewed-by: Nick Dyer <n...@shmanahar.org>

> ---
> Also, in addition to changing the size of the read I moved the query
> buffer. I figured that since the query buffer is only acceessed in the
> rmi_f54_detect function it was not necessary keep it in f54_data. The
> parsed values are already being stored in f54_data.
> 
> Thanks,
> Andrew
> 
> 
>  drivers/input/rmi4/rmi_f54.c | 17 +++--
>  1 file changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
> index dea63e2..f5206e2 100644
> --- a/drivers/input/rmi4/rmi_f54.c
> +++ b/drivers/input/rmi4/rmi_f54.c
> @@ -31,9 +31,6 @@
>  #define F54_GET_REPORT  1
>  #define F54_FORCE_CAL   2
>  
> -/* Fixed sizes of reports */
> -#define F54_QUERY_LEN27
> -
>  /* F54 capabilities */
>  #define F54_CAP_BASELINE (1 << 2)
>  #define F54_CAP_IMAGE8   (1 << 3)
> @@ -95,7 +92,6 @@ struct rmi_f54_reports {
>  struct f54_data {
>   struct rmi_function *fn;
>  
> - u8 qry[F54_QUERY_LEN];
>   u8 num_rx_electrodes;
>   u8 num_tx_electrodes;
>   u8 capabilities;
> @@ -632,22 +628,23 @@ static int rmi_f54_detect(struct rmi_function *fn)
>  {
>   int error;
>   struct f54_data *f54;
> + u8 buf[6];
>  
>   f54 = dev_get_drvdata(>dev);
>  
>   error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
> ->qry, sizeof(f54->qry));
> +buf, sizeof(buf));
>   if (error) {
>   dev_err(>dev, "%s: Failed to query F54 properties\n",
>   __func__);
>   return error;
>   }
>  
> - f54->num_rx_electrodes = f54->qry[0];
> - f54->num_tx_electrodes = f54->qry[1];
> - f54->capabilities = f54->qry[2];
> - f54->clock_rate = f54->qry[3] | (f54->qry[4] << 8);
> - f54->family = f54->qry[5];
> + f54->num_rx_electrodes = buf[0];
> + f54->num_tx_electrodes = buf[1];
> + f54->capabilities = buf[2];
> + f54->clock_rate = buf[3] | (buf[4] << 8);
> + f54->family = buf[5];
>  
>   rmi_dbg(RMI_DEBUG_FN, >dev, "F54 num_rx_electrodes: %d\n",
>   f54->num_rx_electrodes);
> -- 
> 2.7.4
> 


Re: [PATCH] Input: synaptics-rmi4 - Only read the F54 query registers which are used

2017-06-22 Thread Nick Dyer
On Tue, Jun 20, 2017 at 04:08:48PM -0700, Andrew Duggan wrote:
> The F54 driver is currently only using the first 6 bytes of F54 so there
> is no need to read all 27 bytes. Some Dell systems
> (Dell XP13 9333 and similar) have an issue with the touchpad or I2C bus
> when readiing reports larger then 16 bytes. Reads larger then 16 bytes
> are reported in two HID reports. Something about the back to back
> reports seems to cause the next read to report incorrect data. This
> results in F30 failing to load and the click button failing to work.
> 
> Previous issues with the I2C controller or touchpad were addressed in:
> commit 5b65c2a02966 ("HID: rmi: check sanity of the incoming report")
> 
> Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=195949
> Signed-off-by: Andrew Duggan 

Looks fine to me.

Reviewed-by: Nick Dyer 

> ---
> Also, in addition to changing the size of the read I moved the query
> buffer. I figured that since the query buffer is only acceessed in the
> rmi_f54_detect function it was not necessary keep it in f54_data. The
> parsed values are already being stored in f54_data.
> 
> Thanks,
> Andrew
> 
> 
>  drivers/input/rmi4/rmi_f54.c | 17 +++--
>  1 file changed, 7 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
> index dea63e2..f5206e2 100644
> --- a/drivers/input/rmi4/rmi_f54.c
> +++ b/drivers/input/rmi4/rmi_f54.c
> @@ -31,9 +31,6 @@
>  #define F54_GET_REPORT  1
>  #define F54_FORCE_CAL   2
>  
> -/* Fixed sizes of reports */
> -#define F54_QUERY_LEN27
> -
>  /* F54 capabilities */
>  #define F54_CAP_BASELINE (1 << 2)
>  #define F54_CAP_IMAGE8   (1 << 3)
> @@ -95,7 +92,6 @@ struct rmi_f54_reports {
>  struct f54_data {
>   struct rmi_function *fn;
>  
> - u8 qry[F54_QUERY_LEN];
>   u8 num_rx_electrodes;
>   u8 num_tx_electrodes;
>   u8 capabilities;
> @@ -632,22 +628,23 @@ static int rmi_f54_detect(struct rmi_function *fn)
>  {
>   int error;
>   struct f54_data *f54;
> + u8 buf[6];
>  
>   f54 = dev_get_drvdata(>dev);
>  
>   error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
> ->qry, sizeof(f54->qry));
> +buf, sizeof(buf));
>   if (error) {
>   dev_err(>dev, "%s: Failed to query F54 properties\n",
>   __func__);
>   return error;
>   }
>  
> - f54->num_rx_electrodes = f54->qry[0];
> - f54->num_tx_electrodes = f54->qry[1];
> - f54->capabilities = f54->qry[2];
> - f54->clock_rate = f54->qry[3] | (f54->qry[4] << 8);
> - f54->family = f54->qry[5];
> + f54->num_rx_electrodes = buf[0];
> + f54->num_tx_electrodes = buf[1];
> + f54->capabilities = buf[2];
> + f54->clock_rate = buf[3] | (buf[4] << 8);
> + f54->family = buf[5];
>  
>   rmi_dbg(RMI_DEBUG_FN, >dev, "F54 num_rx_electrodes: %d\n",
>   f54->num_rx_electrodes);
> -- 
> 2.7.4
> 


Re: [PATCH] Input: synaptics-rmi4 - use %ph to form F34 configuration ID

2017-05-31 Thread Nick Dyer
On Tue, May 30, 2017 at 09:59:13AM -0700, Dmitry Torokhov wrote:
> On Tue, May 30, 2017 at 10:23:58AM +0200, Benjamin Tissoires wrote:
> > On May 29 2017 or thereabouts, Dmitry Torokhov wrote:
> > > Instead of printing bytes one by one, let's use %phN to print the buffer 
> > > in
> > > one go.
> > > 
> > > Also use hweight8 to count number of partitions instead of inspecting it
> > > bit by bit.
> > > 
> > > Signed-off-by: Dmitry Torokhov <dmitry.torok...@gmail.com>
> > > ---
> > 
> > Looks good to me:
> > Reviewed-by: Benjamin Tissoires <benjamin.tissoi...@redhat.com>
> 
> Hm, I just realized taht we'd go from upper to lowercase hex digits. I
> think it should be OK, but I'd like to hear interested parties (Nick).
> 
> Or we'd need to introduce %pH I guess.

Hi Dmitry-

I can't see any issue with this: all the firmwares I've encountered are
purely numerical anyway.

Tested-by: Nick Dyer <n...@shmanahar.org>

> 
> > 
> > Cheers,
> > Benjamin
> > 
> > >  drivers/input/rmi4/rmi_f34v7.c | 22 --
> > >  1 file changed, 8 insertions(+), 14 deletions(-)
> > > 
> > > diff --git a/drivers/input/rmi4/rmi_f34v7.c 
> > > b/drivers/input/rmi4/rmi_f34v7.c
> > > index ae2db1c3aebf..3991d2943660 100644
> > > --- a/drivers/input/rmi4/rmi_f34v7.c
> > > +++ b/drivers/input/rmi4/rmi_f34v7.c
> > > @@ -9,13 +9,14 @@
> > >   * the Free Software Foundation.
> > >   */
> > >  
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > -#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  
> > >  #include "rmi_driver.h"
> > >  #include "rmi_f34.h"
> > > @@ -464,7 +465,7 @@ static int rmi_f34v7_read_queries_bl_version(struct 
> > > f34_data *f34)
> > >  static int rmi_f34v7_read_queries(struct f34_data *f34)
> > >  {
> > >   int ret;
> > > - int i, j;
> > > + int i;
> > >   u8 base;
> > >   int offset;
> > >   u8 *ptable;
> > > @@ -519,9 +520,6 @@ static int rmi_f34v7_read_queries(struct f34_data 
> > > *f34)
> > >  
> > >   if (query_0 & HAS_CONFIG_ID) {
> > >   u8 f34_ctrl[CONFIG_ID_SIZE];
> > > - int i = 0;
> > > - u8 *p = f34->configuration_id;
> > > - *p = '\0';
> > >  
> > >   ret = rmi_read_block(f34->fn->rmi_dev,
> > >   f34->fn->fd.control_base_addr,
> > > @@ -531,13 +529,11 @@ static int rmi_f34v7_read_queries(struct f34_data 
> > > *f34)
> > >   return ret;
> > >  
> > >   /* Eat leading zeros */
> > > - while (i < sizeof(f34_ctrl) && !f34_ctrl[i])
> > > - i++;
> > > + for (i = 0; i < sizeof(f34_ctrl) - 1 && !f34_ctrl[i]; i++)
> > > + /* Empty */;
> > >  
> > > - for (; i < sizeof(f34_ctrl); i++)
> > > - p += snprintf(p, f34->configuration_id
> > > -   + sizeof(f34->configuration_id) - p,
> > > -   "%02X", f34_ctrl[i]);
> > > + snprintf(f34->configuration_id, sizeof(f34->configuration_id),
> > > +  "%*phN", (int)sizeof(f34_ctrl) - i, f34_ctrl + i);
> > >  
> > >   rmi_dbg(RMI_DEBUG_FN, >fn->dev, "Configuration ID: %s\n",
> > >   f34->configuration_id);
> > > @@ -545,9 +541,7 @@ static int rmi_f34v7_read_queries(struct f34_data 
> > > *f34)
> > >  
> > >   f34->v7.partitions = 0;
> > >   for (i = 0; i < sizeof(query_1_7.partition_support); i++)
> > > - for (j = 0; j < 8; j++)
> > > - if (query_1_7.partition_support[i] & (1 << j))
> > > - f34->v7.partitions++;
> > > + f34->v7.partitions += hweight8(query_1_7.partition_support[i]);
> > >  
> > >   rmi_dbg(RMI_DEBUG_FN, >fn->dev, "%s: Supported partitions: %*ph\n",
> > >   __func__, sizeof(query_1_7.partition_support),
> > > -- 
> > > 2.13.0.219.gdb65acc882-goog
> > > 
> > > 
> > > -- 
> > > Dmitry
> 
> -- 
> Dmitry


Re: [PATCH] Input: synaptics-rmi4 - use %ph to form F34 configuration ID

2017-05-31 Thread Nick Dyer
On Tue, May 30, 2017 at 09:59:13AM -0700, Dmitry Torokhov wrote:
> On Tue, May 30, 2017 at 10:23:58AM +0200, Benjamin Tissoires wrote:
> > On May 29 2017 or thereabouts, Dmitry Torokhov wrote:
> > > Instead of printing bytes one by one, let's use %phN to print the buffer 
> > > in
> > > one go.
> > > 
> > > Also use hweight8 to count number of partitions instead of inspecting it
> > > bit by bit.
> > > 
> > > Signed-off-by: Dmitry Torokhov 
> > > ---
> > 
> > Looks good to me:
> > Reviewed-by: Benjamin Tissoires 
> 
> Hm, I just realized taht we'd go from upper to lowercase hex digits. I
> think it should be OK, but I'd like to hear interested parties (Nick).
> 
> Or we'd need to introduce %pH I guess.

Hi Dmitry-

I can't see any issue with this: all the firmwares I've encountered are
purely numerical anyway.

Tested-by: Nick Dyer 

> 
> > 
> > Cheers,
> > Benjamin
> > 
> > >  drivers/input/rmi4/rmi_f34v7.c | 22 --
> > >  1 file changed, 8 insertions(+), 14 deletions(-)
> > > 
> > > diff --git a/drivers/input/rmi4/rmi_f34v7.c 
> > > b/drivers/input/rmi4/rmi_f34v7.c
> > > index ae2db1c3aebf..3991d2943660 100644
> > > --- a/drivers/input/rmi4/rmi_f34v7.c
> > > +++ b/drivers/input/rmi4/rmi_f34v7.c
> > > @@ -9,13 +9,14 @@
> > >   * the Free Software Foundation.
> > >   */
> > >  
> > > +#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > -#include 
> > >  #include 
> > >  #include 
> > >  #include 
> > > +#include 
> > >  
> > >  #include "rmi_driver.h"
> > >  #include "rmi_f34.h"
> > > @@ -464,7 +465,7 @@ static int rmi_f34v7_read_queries_bl_version(struct 
> > > f34_data *f34)
> > >  static int rmi_f34v7_read_queries(struct f34_data *f34)
> > >  {
> > >   int ret;
> > > - int i, j;
> > > + int i;
> > >   u8 base;
> > >   int offset;
> > >   u8 *ptable;
> > > @@ -519,9 +520,6 @@ static int rmi_f34v7_read_queries(struct f34_data 
> > > *f34)
> > >  
> > >   if (query_0 & HAS_CONFIG_ID) {
> > >   u8 f34_ctrl[CONFIG_ID_SIZE];
> > > - int i = 0;
> > > - u8 *p = f34->configuration_id;
> > > - *p = '\0';
> > >  
> > >   ret = rmi_read_block(f34->fn->rmi_dev,
> > >   f34->fn->fd.control_base_addr,
> > > @@ -531,13 +529,11 @@ static int rmi_f34v7_read_queries(struct f34_data 
> > > *f34)
> > >   return ret;
> > >  
> > >   /* Eat leading zeros */
> > > - while (i < sizeof(f34_ctrl) && !f34_ctrl[i])
> > > - i++;
> > > + for (i = 0; i < sizeof(f34_ctrl) - 1 && !f34_ctrl[i]; i++)
> > > + /* Empty */;
> > >  
> > > - for (; i < sizeof(f34_ctrl); i++)
> > > - p += snprintf(p, f34->configuration_id
> > > -   + sizeof(f34->configuration_id) - p,
> > > -   "%02X", f34_ctrl[i]);
> > > + snprintf(f34->configuration_id, sizeof(f34->configuration_id),
> > > +  "%*phN", (int)sizeof(f34_ctrl) - i, f34_ctrl + i);
> > >  
> > >   rmi_dbg(RMI_DEBUG_FN, >fn->dev, "Configuration ID: %s\n",
> > >   f34->configuration_id);
> > > @@ -545,9 +541,7 @@ static int rmi_f34v7_read_queries(struct f34_data 
> > > *f34)
> > >  
> > >   f34->v7.partitions = 0;
> > >   for (i = 0; i < sizeof(query_1_7.partition_support); i++)
> > > - for (j = 0; j < 8; j++)
> > > - if (query_1_7.partition_support[i] & (1 << j))
> > > - f34->v7.partitions++;
> > > + f34->v7.partitions += hweight8(query_1_7.partition_support[i]);
> > >  
> > >   rmi_dbg(RMI_DEBUG_FN, >fn->dev, "%s: Supported partitions: %*ph\n",
> > >   __func__, sizeof(query_1_7.partition_support),
> > > -- 
> > > 2.13.0.219.gdb65acc882-goog
> > > 
> > > 
> > > -- 
> > > Dmitry
> 
> -- 
> Dmitry


Re: Synaptics RMI4 touchpad regression in 4.11-rc1

2017-03-14 Thread Nick Dyer
On Mon, Mar 13, 2017 at 10:10:22PM -0700, Cameron Gutman wrote:
> > Compared to hid-multitouch, the RMI stack seems to have
> > completely broken palm rejection and introduced some random
> > jumpiness during fine pointing motions. I don't know if these
> > issues are caused by the above errors or are a separate issue.
> > 
> > The error about the bootloader version not being recognized just
> > means that updating the firmware is not supported on this touchpad.
> > It is only the F34 firmware update functionality which is failing to
> > load. The palm rejection and jumps are not related to this error.
> > 
> 
> Maybe that code path should be changed to not make as much noise when
> it runs on known unsupported hardware. Something like the attached
> patch?

> ---
> diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c
> index 56c6c39..1291d9a 100644
> --- a/drivers/input/rmi4/rmi_f34v7.c
> +++ b/drivers/input/rmi4/rmi_f34v7.c
> @@ -1369,9 +1369,9 @@ int rmi_f34v7_probe(struct f34_data *f34)
>   } else if (f34->bootloader_id[1] == 7) {
>   f34->bl_version = 7;
>   } else {
> - dev_err(>fn->dev, "%s: Unrecognized bootloader version\n",
> - __func__);
> - return -EINVAL;
> + dev_info(>fn->dev, "%s: Unsupported bootloader version: 
> %u\n",
> + __func__, f34->bootloader_id[1]);
> + return -ENODEV;
>   }
>  
>   memset(>v7.blkcount, 0x00, sizeof(f34->v7.blkcount));

I'm afraid I'm responsible for this. I agree it's very unlikely to be
related to your other issues.

One approach to suppress the extra output would be to turn off
CONFIG_RMI_F34. I think your proposed change in wording would be fine,
though.

cheers

Nick


Re: Synaptics RMI4 touchpad regression in 4.11-rc1

2017-03-14 Thread Nick Dyer
On Mon, Mar 13, 2017 at 10:10:22PM -0700, Cameron Gutman wrote:
> > Compared to hid-multitouch, the RMI stack seems to have
> > completely broken palm rejection and introduced some random
> > jumpiness during fine pointing motions. I don't know if these
> > issues are caused by the above errors or are a separate issue.
> > 
> > The error about the bootloader version not being recognized just
> > means that updating the firmware is not supported on this touchpad.
> > It is only the F34 firmware update functionality which is failing to
> > load. The palm rejection and jumps are not related to this error.
> > 
> 
> Maybe that code path should be changed to not make as much noise when
> it runs on known unsupported hardware. Something like the attached
> patch?

> ---
> diff --git a/drivers/input/rmi4/rmi_f34v7.c b/drivers/input/rmi4/rmi_f34v7.c
> index 56c6c39..1291d9a 100644
> --- a/drivers/input/rmi4/rmi_f34v7.c
> +++ b/drivers/input/rmi4/rmi_f34v7.c
> @@ -1369,9 +1369,9 @@ int rmi_f34v7_probe(struct f34_data *f34)
>   } else if (f34->bootloader_id[1] == 7) {
>   f34->bl_version = 7;
>   } else {
> - dev_err(>fn->dev, "%s: Unrecognized bootloader version\n",
> - __func__);
> - return -EINVAL;
> + dev_info(>fn->dev, "%s: Unsupported bootloader version: 
> %u\n",
> + __func__, f34->bootloader_id[1]);
> + return -ENODEV;
>   }
>  
>   memset(>v7.blkcount, 0x00, sizeof(f34->v7.blkcount));

I'm afraid I'm responsible for this. I agree it's very unlikely to be
related to your other issues.

One approach to suppress the extra output would be to turn off
CONFIG_RMI_F34. I think your proposed change in wording would be fine,
though.

cheers

Nick


Re: [PATCH] Input: synaptics-rmi4 - create firmware update sysfs attribute in F34

2017-02-13 Thread Nick Dyer
On Sun, Feb 12, 2017 at 04:02:51PM -0800, Dmitry Torokhov wrote:
> On Sun, Feb 12, 2017 at 10:50:56PM +0000, Nick Dyer wrote:
> > On Thu, Feb 09, 2017 at 01:25:08PM -0800, Dmitry Torokhov wrote:
> > > There is no need to create sysfs attributes in the main driver core,
> > > let F34 implementation do that.
> > 
> > I haven't tested this yet, but I did try creating/removing the sysfs
> > entries in the f34 function probe/remove as you're suggesting when I
> > wrote the F34 support.
> > 
> > The problem is that when we do a firmware update, we have to tear down
> > the function list (because most of the functions are not there during
> > firmware update and they may in fact come back different). Which removes
> > the sysfs entries, meaning it's rather like sawing off the branch you're
> > sitting on, and it crashes almost immediately. I couldn't think of a
> > cleaner way to solve it that the current implementation.
> 
> Oh, I see. Well, that means that the current implementation is quite
> broken, as you'll end up referencing freed and potentially reused memory
> after firmware update. It looks like we'll need to make sure we do not
> reference F34 memory unless we know it is there. That means we'll have
> to pull update status and FW update mutex into the RMI device itself as
> it is something that stays around even if we destroy and rebuild
> function list.

I see what you mean. The code does check that f34_container isn't null
(eg in rmi_driver_configuration_id_show) but since it may be accessed
from multiple threads it needs a mutex around it.


Re: [PATCH] Input: synaptics-rmi4 - create firmware update sysfs attribute in F34

2017-02-13 Thread Nick Dyer
On Sun, Feb 12, 2017 at 04:02:51PM -0800, Dmitry Torokhov wrote:
> On Sun, Feb 12, 2017 at 10:50:56PM +0000, Nick Dyer wrote:
> > On Thu, Feb 09, 2017 at 01:25:08PM -0800, Dmitry Torokhov wrote:
> > > There is no need to create sysfs attributes in the main driver core,
> > > let F34 implementation do that.
> > 
> > I haven't tested this yet, but I did try creating/removing the sysfs
> > entries in the f34 function probe/remove as you're suggesting when I
> > wrote the F34 support.
> > 
> > The problem is that when we do a firmware update, we have to tear down
> > the function list (because most of the functions are not there during
> > firmware update and they may in fact come back different). Which removes
> > the sysfs entries, meaning it's rather like sawing off the branch you're
> > sitting on, and it crashes almost immediately. I couldn't think of a
> > cleaner way to solve it that the current implementation.
> 
> Oh, I see. Well, that means that the current implementation is quite
> broken, as you'll end up referencing freed and potentially reused memory
> after firmware update. It looks like we'll need to make sure we do not
> reference F34 memory unless we know it is there. That means we'll have
> to pull update status and FW update mutex into the RMI device itself as
> it is something that stays around even if we destroy and rebuild
> function list.

I see what you mean. The code does check that f34_container isn't null
(eg in rmi_driver_configuration_id_show) but since it may be accessed
from multiple threads it needs a mutex around it.


Re: [PATCH] Input: synaptics-rmi4 - create firmware update sysfs attribute in F34

2017-02-12 Thread Nick Dyer
On Thu, Feb 09, 2017 at 01:25:08PM -0800, Dmitry Torokhov wrote:
> There is no need to create sysfs attributes in the main driver core,
> let F34 implementation do that.

Hi Dmitry-

I haven't tested this yet, but I did try creating/removing the sysfs
entries in the f34 function probe/remove as you're suggesting when I
wrote the F34 support.

The problem is that when we do a firmware update, we have to tear down
the function list (because most of the functions are not there during
firmware update and they may in fact come back different). Which removes
the sysfs entries, meaning it's rather like sawing off the branch you're
sitting on, and it crashes almost immediately. I couldn't think of a
cleaner way to solve it that the current implementation.

cheers

Nick

> Signed-off-by: Dmitry Torokhov 
> ---
>  drivers/input/rmi4/rmi_driver.c |  5 ---
>  drivers/input/rmi4/rmi_driver.h | 14 ---
>  drivers/input/rmi4/rmi_f34.c| 87 
> +++--
>  3 files changed, 50 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index d64fc92858f2..d9cfe4ec93fa 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -1001,7 +1001,6 @@ static int rmi_driver_remove(struct device *dev)
>  
>   rmi_disable_irq(rmi_dev, false);
>  
> - rmi_f34_remove_sysfs(rmi_dev);
>   rmi_free_function_list(rmi_dev);
>  
>   return 0;
> @@ -1215,10 +1214,6 @@ static int rmi_driver_probe(struct device *dev)
>   if (retval)
>   goto err;
>  
> - retval = rmi_f34_create_sysfs(rmi_dev);
> - if (retval)
> - goto err;
> -
>   if (data->input) {
>   rmi_driver_set_input_name(rmi_dev, data->input);
>   if (!rmi_dev->xport->input) {
> diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
> index f1a2a2266022..1ada14d7d005 100644
> --- a/drivers/input/rmi4/rmi_driver.h
> +++ b/drivers/input/rmi4/rmi_driver.h
> @@ -120,20 +120,6 @@ static inline int rmi_f03_overwrite_button(struct 
> rmi_function *fn,
>  static inline void rmi_f03_commit_buttons(struct rmi_function *fn) {}
>  #endif
>  
> -#ifdef CONFIG_RMI4_F34
> -int rmi_f34_create_sysfs(struct rmi_device *rmi_dev);
> -void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev);
> -#else
> -static inline int rmi_f34_create_sysfs(struct rmi_device *rmi_dev)
> -{
> - return 0;
> -}
> -
> -static inline void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev)
> -{
> -}
> -#endif /* CONFIG_RMI_F34 */
> -
>  extern struct rmi_function_handler rmi_f01_handler;
>  extern struct rmi_function_handler rmi_f03_handler;
>  extern struct rmi_function_handler rmi_f11_handler;
> diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
> index 425fe140e9df..d4d5297d5a8b 100644
> --- a/drivers/input/rmi4/rmi_f34.c
> +++ b/drivers/input/rmi4/rmi_f34.c
> @@ -509,33 +509,21 @@ static struct attribute_group rmi_firmware_attr_group = 
> {
>   .attrs = rmi_firmware_attrs,
>  };
>  
> -static int rmi_f34_probe(struct rmi_function *fn)
> +static int rmi_f34v5_probe(struct f34_data *f34)
>  {
> - struct f34_data *f34;
> - unsigned char f34_queries[9];
> + struct rmi_function *fn = f34->fn;
> + u8 f34_queries[9];
>   bool has_config_id;
> - u8 version = fn->fd.function_version;
> - int ret;
> -
> - f34 = devm_kzalloc(>dev, sizeof(struct f34_data), GFP_KERNEL);
> - if (!f34)
> - return -ENOMEM;
> -
> - f34->fn = fn;
> - dev_set_drvdata(>dev, f34);
> -
> - /* v5 code only supported version 0, try V7 probe */
> - if (version > 0)
> - return rmi_f34v7_probe(f34);
> + int error;
>  
>   f34->bl_version = 5;
>  
> - ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
> -  f34_queries, sizeof(f34_queries));
> - if (ret) {
> - dev_err(>dev, "%s: Failed to query properties\n",
> - __func__);
> - return ret;
> + error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
> +f34_queries, sizeof(f34_queries));
> + if (error) {
> + dev_err(>dev, "%s: Failed to query properties: %d\n",
> + __func__, error);
> + return error;
>   }
>  
>   snprintf(f34->bootloader_id, sizeof(f34->bootloader_id),
> @@ -548,8 +536,8 @@ static int rmi_f34_probe(struct rmi_function *fn)
>   f34->v5.fw_blocks = get_unaligned_le16(_queries[5]);
>   f34->v5.config_blocks = get_unaligned_le16(_queries[7]);
>   f34->v5.ctrl_address = fn->fd.data_base_addr + F34_BLOCK_DATA_OFFSET +
> - f34->v5.block_size;
> - has_config_id = f34_queries[2] & (1 << 2);
> + f34->v5.block_size;
> + has_config_id = f34_queries[2] & BIT(2);
>  
>   rmi_dbg(RMI_DEBUG_FN, >dev, "Bootloader ID: %s\n",

Re: [PATCH] Input: synaptics-rmi4 - create firmware update sysfs attribute in F34

2017-02-12 Thread Nick Dyer
On Thu, Feb 09, 2017 at 01:25:08PM -0800, Dmitry Torokhov wrote:
> There is no need to create sysfs attributes in the main driver core,
> let F34 implementation do that.

Hi Dmitry-

I haven't tested this yet, but I did try creating/removing the sysfs
entries in the f34 function probe/remove as you're suggesting when I
wrote the F34 support.

The problem is that when we do a firmware update, we have to tear down
the function list (because most of the functions are not there during
firmware update and they may in fact come back different). Which removes
the sysfs entries, meaning it's rather like sawing off the branch you're
sitting on, and it crashes almost immediately. I couldn't think of a
cleaner way to solve it that the current implementation.

cheers

Nick

> Signed-off-by: Dmitry Torokhov 
> ---
>  drivers/input/rmi4/rmi_driver.c |  5 ---
>  drivers/input/rmi4/rmi_driver.h | 14 ---
>  drivers/input/rmi4/rmi_f34.c| 87 
> +++--
>  3 files changed, 50 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
> index d64fc92858f2..d9cfe4ec93fa 100644
> --- a/drivers/input/rmi4/rmi_driver.c
> +++ b/drivers/input/rmi4/rmi_driver.c
> @@ -1001,7 +1001,6 @@ static int rmi_driver_remove(struct device *dev)
>  
>   rmi_disable_irq(rmi_dev, false);
>  
> - rmi_f34_remove_sysfs(rmi_dev);
>   rmi_free_function_list(rmi_dev);
>  
>   return 0;
> @@ -1215,10 +1214,6 @@ static int rmi_driver_probe(struct device *dev)
>   if (retval)
>   goto err;
>  
> - retval = rmi_f34_create_sysfs(rmi_dev);
> - if (retval)
> - goto err;
> -
>   if (data->input) {
>   rmi_driver_set_input_name(rmi_dev, data->input);
>   if (!rmi_dev->xport->input) {
> diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
> index f1a2a2266022..1ada14d7d005 100644
> --- a/drivers/input/rmi4/rmi_driver.h
> +++ b/drivers/input/rmi4/rmi_driver.h
> @@ -120,20 +120,6 @@ static inline int rmi_f03_overwrite_button(struct 
> rmi_function *fn,
>  static inline void rmi_f03_commit_buttons(struct rmi_function *fn) {}
>  #endif
>  
> -#ifdef CONFIG_RMI4_F34
> -int rmi_f34_create_sysfs(struct rmi_device *rmi_dev);
> -void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev);
> -#else
> -static inline int rmi_f34_create_sysfs(struct rmi_device *rmi_dev)
> -{
> - return 0;
> -}
> -
> -static inline void rmi_f34_remove_sysfs(struct rmi_device *rmi_dev)
> -{
> -}
> -#endif /* CONFIG_RMI_F34 */
> -
>  extern struct rmi_function_handler rmi_f01_handler;
>  extern struct rmi_function_handler rmi_f03_handler;
>  extern struct rmi_function_handler rmi_f11_handler;
> diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
> index 425fe140e9df..d4d5297d5a8b 100644
> --- a/drivers/input/rmi4/rmi_f34.c
> +++ b/drivers/input/rmi4/rmi_f34.c
> @@ -509,33 +509,21 @@ static struct attribute_group rmi_firmware_attr_group = 
> {
>   .attrs = rmi_firmware_attrs,
>  };
>  
> -static int rmi_f34_probe(struct rmi_function *fn)
> +static int rmi_f34v5_probe(struct f34_data *f34)
>  {
> - struct f34_data *f34;
> - unsigned char f34_queries[9];
> + struct rmi_function *fn = f34->fn;
> + u8 f34_queries[9];
>   bool has_config_id;
> - u8 version = fn->fd.function_version;
> - int ret;
> -
> - f34 = devm_kzalloc(>dev, sizeof(struct f34_data), GFP_KERNEL);
> - if (!f34)
> - return -ENOMEM;
> -
> - f34->fn = fn;
> - dev_set_drvdata(>dev, f34);
> -
> - /* v5 code only supported version 0, try V7 probe */
> - if (version > 0)
> - return rmi_f34v7_probe(f34);
> + int error;
>  
>   f34->bl_version = 5;
>  
> - ret = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
> -  f34_queries, sizeof(f34_queries));
> - if (ret) {
> - dev_err(>dev, "%s: Failed to query properties\n",
> - __func__);
> - return ret;
> + error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
> +f34_queries, sizeof(f34_queries));
> + if (error) {
> + dev_err(>dev, "%s: Failed to query properties: %d\n",
> + __func__, error);
> + return error;
>   }
>  
>   snprintf(f34->bootloader_id, sizeof(f34->bootloader_id),
> @@ -548,8 +536,8 @@ static int rmi_f34_probe(struct rmi_function *fn)
>   f34->v5.fw_blocks = get_unaligned_le16(_queries[5]);
>   f34->v5.config_blocks = get_unaligned_le16(_queries[7]);
>   f34->v5.ctrl_address = fn->fd.data_base_addr + F34_BLOCK_DATA_OFFSET +
> - f34->v5.block_size;
> - has_config_id = f34_queries[2] & (1 << 2);
> + f34->v5.block_size;
> + has_config_id = f34_queries[2] & BIT(2);
>  
>   rmi_dbg(RMI_DEBUG_FN, >dev, "Bootloader ID: %s\n",
>   

Re: [PATCH v9] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-11 Thread Nick Dyer
On Sun, Dec 11, 2016 at 12:03:49AM -0800, Dmitry Torokhov wrote:
> On Sun, Dec 11, 2016 at 12:18:26AM +0000, Nick Dyer wrote:
> > +static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data 
> > *f34,
> > +  const u8 *image)
> > +{
> > +   int i;
> > +   int num_of_containers;
> > +   unsigned int addr;
> > +   unsigned int container_id;
> > +   unsigned int length;
> > +   const u8 *content;
> > +   struct container_descriptor *descriptor;
> > +
> > +   BUG_ON(f34->v7.img.bootloader.size < 4);
> 
> Killing the box because you got bad firmware is not very nice...
> 
> > +
> > +   num_of_containers = (f34->v7.img.bootloader.size - 4) / 4;
> 
> Wouldn't
> 
>   num_of_containes = f34->v7.img.bootloader.size / 4 - 1;
> 
> give the same result but be less "suspicious". The variable is 'int' so
> for size < 4 we'll get a negative and the loop won't execute.

Neat!

> > +
> > +   for (i = 1; i <= num_of_containers; i++) {
> > +   addr = get_unaligned_le32(f34->v7.img.bootloader.data + i*4);
> > +   descriptor = (struct container_descriptor *)(image + addr);
> 
> This casts away constness, which is not nice. DOes it still work if you
> apply the below on top?

I've run it through a few flash cycles with no issues.

Tested-by: Nick Dyer <n...@shmanahar.org>

> Thanks!

Thanks for your help with this.

> 
> -- 
> Dmitry
> 
> 
> Input: synaptics-rmi4 - misc f34v7 changes
> 
> From: Dmitry Torokhov <dmitry.torok...@gmail.com>
> 
> Signed-off-by: Dmitry Torokhov <dmitry.torok...@gmail.com>
> ---
>  drivers/input/rmi4/rmi_f34.h   |6 ++--
>  drivers/input/rmi4/rmi_f34v7.c |   64 
> 
>  2 files changed, 28 insertions(+), 42 deletions(-)


Re: [PATCH v9] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-11 Thread Nick Dyer
On Sun, Dec 11, 2016 at 12:03:49AM -0800, Dmitry Torokhov wrote:
> On Sun, Dec 11, 2016 at 12:18:26AM +0000, Nick Dyer wrote:
> > +static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data 
> > *f34,
> > +  const u8 *image)
> > +{
> > +   int i;
> > +   int num_of_containers;
> > +   unsigned int addr;
> > +   unsigned int container_id;
> > +   unsigned int length;
> > +   const u8 *content;
> > +   struct container_descriptor *descriptor;
> > +
> > +   BUG_ON(f34->v7.img.bootloader.size < 4);
> 
> Killing the box because you got bad firmware is not very nice...
> 
> > +
> > +   num_of_containers = (f34->v7.img.bootloader.size - 4) / 4;
> 
> Wouldn't
> 
>   num_of_containes = f34->v7.img.bootloader.size / 4 - 1;
> 
> give the same result but be less "suspicious". The variable is 'int' so
> for size < 4 we'll get a negative and the loop won't execute.

Neat!

> > +
> > +   for (i = 1; i <= num_of_containers; i++) {
> > +   addr = get_unaligned_le32(f34->v7.img.bootloader.data + i*4);
> > +   descriptor = (struct container_descriptor *)(image + addr);
> 
> This casts away constness, which is not nice. DOes it still work if you
> apply the below on top?

I've run it through a few flash cycles with no issues.

Tested-by: Nick Dyer 

> Thanks!

Thanks for your help with this.

> 
> -- 
> Dmitry
> 
> 
> Input: synaptics-rmi4 - misc f34v7 changes
> 
> From: Dmitry Torokhov 
> 
> Signed-off-by: Dmitry Torokhov 
> ---
>  drivers/input/rmi4/rmi_f34.h   |6 ++--
>  drivers/input/rmi4/rmi_f34v7.c |   64 
> 
>  2 files changed, 28 insertions(+), 42 deletions(-)


[PATCH v9] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-10 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Chris Healy <cphe...@gmail.com>
---

Changes in v9:
- Fix strangeness introduced in conversion to proper le32_to_cpu() APIs
- Various other minor tidyups.

Changes in v8:
- Address Dmitry Torokhov review comments.

Changes in v7:
- Removed bitfields (would cause issues on big endian archs)

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy

 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   40 +-
 drivers/input/rmi4/rmi_f34.h|  250 ++-
 drivers/input/rmi4/rmi_f34v7.c  | 1384 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1700 insertions(+), 34 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index a199cbe..9aaac3d 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -8,7 +8,7 @@ rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
 
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 05a3c4b..cb6efe6 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -544,7 +544,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -749,41 +749,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *irq_coun

[PATCH v9] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-10 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer 
Tested-by: Chris Healy 
---

Changes in v9:
- Fix strangeness introduced in conversion to proper le32_to_cpu() APIs
- Various other minor tidyups.

Changes in v8:
- Address Dmitry Torokhov review comments.

Changes in v7:
- Removed bitfields (would cause issues on big endian archs)

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy

 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   40 +-
 drivers/input/rmi4/rmi_f34.h|  250 ++-
 drivers/input/rmi4/rmi_f34v7.c  | 1384 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1700 insertions(+), 34 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index a199cbe..9aaac3d 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -8,7 +8,7 @@ rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
 
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 05a3c4b..cb6efe6 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -544,7 +544,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -749,41 +749,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *irq_count = ctx;
+   int ret;
 
*irq_count += pdt-&

Re: [PATCH v8] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-10 Thread Nick Dyer
On Wed, Dec 07, 2016 at 06:14:18PM -0800, Dmitry Torokhov wrote:
> On Mon, Dec 05, 2016 at 01:02:49AM +0000, Nick Dyer wrote:
> > +static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data 
> > *f34,
> > +  const u8 *image)
> > +{
> > +   int i;
> > +   u8 num_of_containers;
> > +   unsigned int addr;
> > +   unsigned int container_id;
> > +   unsigned int length;
> > +   const u8 *content;
> > +   struct container_descriptor *descriptor;
> > +
> > +   BUG_ON(f34->v7.img.bootloader.size < 4);
> > +
> > +   num_of_containers = (f34->v7.img.bootloader.size - 4) / 4;
> > +
> > +   for (i = 1; i <= num_of_containers; i++) {
> > +   addr = le32_to_cpu(f34->v7.img.bootloader.data + (i * 4));
> 
> This cannot possibly be right. "f34->v7.img.bootloader.data + (i * 4)"
> is a pointer in memory, you should not be converting it from le32.
> 
> Did you mean to use le32_to_cpup((__le32 *)(f34->v7.img.bootloader.data
> + (i * 4))) ?

You're quit right. It should be get_unaligned_le32() to read an offset
address from the firmware image. Will be fixed in v9.

Nick


Re: [PATCH v8] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-10 Thread Nick Dyer
On Wed, Dec 07, 2016 at 06:14:18PM -0800, Dmitry Torokhov wrote:
> On Mon, Dec 05, 2016 at 01:02:49AM +0000, Nick Dyer wrote:
> > +static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data 
> > *f34,
> > +  const u8 *image)
> > +{
> > +   int i;
> > +   u8 num_of_containers;
> > +   unsigned int addr;
> > +   unsigned int container_id;
> > +   unsigned int length;
> > +   const u8 *content;
> > +   struct container_descriptor *descriptor;
> > +
> > +   BUG_ON(f34->v7.img.bootloader.size < 4);
> > +
> > +   num_of_containers = (f34->v7.img.bootloader.size - 4) / 4;
> > +
> > +   for (i = 1; i <= num_of_containers; i++) {
> > +   addr = le32_to_cpu(f34->v7.img.bootloader.data + (i * 4));
> 
> This cannot possibly be right. "f34->v7.img.bootloader.data + (i * 4)"
> is a pointer in memory, you should not be converting it from le32.
> 
> Did you mean to use le32_to_cpup((__le32 *)(f34->v7.img.bootloader.data
> + (i * 4))) ?

You're quit right. It should be get_unaligned_le32() to read an offset
address from the firmware image. Will be fixed in v9.

Nick


[PATCH] Input: synaptics-rmi4 - fix debug for sensor clip

2016-12-04 Thread Nick Dyer
The debug would only ever output zero for the clip information.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
---

 drivers/input/rmi4/rmi_f12.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
index 8c5360c..e35c64b 100644
--- a/drivers/input/rmi4/rmi_f12.c
+++ b/drivers/input/rmi4/rmi_f12.c
@@ -71,10 +71,6 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
u8 buf[15];
int pitch_x = 0;
int pitch_y = 0;
-   int clip_x_low = 0;
-   int clip_x_high = 0;
-   int clip_y_low = 0;
-   int clip_y_high = 0;
int rx_receivers = 0;
int tx_receivers = 0;
int sensor_flags = 0;
@@ -127,7 +123,8 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
}
 
rmi_dbg(RMI_DEBUG_FN, >dev, "%s: x low: %d x high: %d y low: %d y 
high: %d\n",
-   __func__, clip_x_low, clip_x_high, clip_y_low, clip_y_high);
+   __func__, sensor->axis_align.clip_x_low, 
sensor->axis_align.clip_x_high,
+   sensor->axis_align.clip_y_low, sensor->axis_align.clip_y_high);
 
if (rmi_register_desc_has_subpacket(item, 3)) {
rx_receivers = buf[offset];
-- 
2.7.4



[PATCH] Input: synaptics-rmi4 - fix debug for sensor clip

2016-12-04 Thread Nick Dyer
The debug would only ever output zero for the clip information.

Signed-off-by: Nick Dyer 
---

 drivers/input/rmi4/rmi_f12.c | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
index 8c5360c..e35c64b 100644
--- a/drivers/input/rmi4/rmi_f12.c
+++ b/drivers/input/rmi4/rmi_f12.c
@@ -71,10 +71,6 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
u8 buf[15];
int pitch_x = 0;
int pitch_y = 0;
-   int clip_x_low = 0;
-   int clip_x_high = 0;
-   int clip_y_low = 0;
-   int clip_y_high = 0;
int rx_receivers = 0;
int tx_receivers = 0;
int sensor_flags = 0;
@@ -127,7 +123,8 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
}
 
rmi_dbg(RMI_DEBUG_FN, >dev, "%s: x low: %d x high: %d y low: %d y 
high: %d\n",
-   __func__, clip_x_low, clip_x_high, clip_y_low, clip_y_high);
+   __func__, sensor->axis_align.clip_x_low, 
sensor->axis_align.clip_x_high,
+   sensor->axis_align.clip_y_low, sensor->axis_align.clip_y_high);
 
if (rmi_register_desc_has_subpacket(item, 3)) {
rx_receivers = buf[offset];
-- 
2.7.4



[PATCH v8] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-04 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Chris Healy <cphe...@gmail.com>
---

Hi Dmitry-

Thanks for the useful review, here is an updated version.

This patch applies on top of dtor/synaptics-rmi4. The F34 V1 support has
already been merged.

Changes in v8:
- Address Dmitry Torokhov review comments.

Changes in v7:
- Removed bitfields (would cause issues on big endian archs)

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy


 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   40 +-
 drivers/input/rmi4/rmi_f34.h|  252 ++-
 drivers/input/rmi4/rmi_f34v7.c  | 1405 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1722 insertions(+), 35 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index a199cbe..9aaac3d 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -8,7 +8,7 @@ rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
 
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 05a3c4b..cb6efe6 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -544,7 +544,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -749,41 +749,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_dr

[PATCH v8] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-12-04 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer 
Tested-by: Chris Healy 
---

Hi Dmitry-

Thanks for the useful review, here is an updated version.

This patch applies on top of dtor/synaptics-rmi4. The F34 V1 support has
already been merged.

Changes in v8:
- Address Dmitry Torokhov review comments.

Changes in v7:
- Removed bitfields (would cause issues on big endian archs)

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy


 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   40 +-
 drivers/input/rmi4/rmi_f34.h|  252 ++-
 drivers/input/rmi4/rmi_f34v7.c  | 1405 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1722 insertions(+), 35 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index a199cbe..9aaac3d 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -8,7 +8,7 @@ rmi_core-$(CONFIG_RMI4_F03) += rmi_f03.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
 
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 05a3c4b..cb6efe6 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -544,7 +544,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -749,41 +749,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *irq_count = 

[PATCH v7] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-11-29 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Chris Healy <cphe...@gmail.com>
---

Hi Dmitry-

Here's an updated version of the F34 V7 support.

This patch applies on top of dtor/synaptics-rmi4. The F34 V1 support has
already been merged.

Changes in v7:
- Removed bitfields (would cause issues on big endian archs)

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy

cheers

Nick


 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   37 +-
 drivers/input/rmi4/rmi_f34.h|  305 -
 drivers/input/rmi4/rmi_f34v7.c  | 1439 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1807 insertions(+), 34 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index e7f4ca6..d6ef939 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,7 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
 
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 2b17d8c..ade26f2 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -527,7 +527,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -737,41 +737,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *

[PATCH v7] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-11-29 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer 
Tested-by: Chris Healy 
---

Hi Dmitry-

Here's an updated version of the F34 V7 support.

This patch applies on top of dtor/synaptics-rmi4. The F34 V1 support has
already been merged.

Changes in v7:
- Removed bitfields (would cause issues on big endian archs)

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy

cheers

Nick


 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   37 +-
 drivers/input/rmi4/rmi_f34.h|  305 -
 drivers/input/rmi4/rmi_f34v7.c  | 1439 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1807 insertions(+), 34 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index e7f4ca6..d6ef939 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,7 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
 
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 2b17d8c..ade26f2 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -527,7 +527,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -737,41 +737,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *irq_count = ctx;
+   int ret;
 
  

Re: [PATCH v6 1/2] Input: synaptics-rmi4 - add support for F34 device reflash

2016-11-23 Thread Nick Dyer
On Wed, Nov 23, 2016 at 12:20:41PM +0100, Benjamin Tissoires wrote:
> On Nov 20 2016 or thereabouts, Nick Dyer wrote:
> > Add support for updating firmware, triggered by a sysfs attribute.
> > 
> > This patch has been tested on Synaptics S7300.
> > 
> > Signed-off-by: Nick Dyer <n...@shmanahar.org>
> > Tested-by: Chris Healy <cphe...@gmail.com>
> > ---
> >  drivers/input/rmi4/Kconfig  |  11 +
> >  drivers/input/rmi4/Makefile |   1 +
> >  drivers/input/rmi4/rmi_bus.c|   3 +
> >  drivers/input/rmi4/rmi_driver.c | 105 ++---
> >  drivers/input/rmi4/rmi_driver.h |  24 ++
> >  drivers/input/rmi4/rmi_f01.c|   6 +
> >  drivers/input/rmi4/rmi_f34.c| 481 
> > 
> >  drivers/input/rmi4/rmi_f34.h|  68 ++
> >  include/linux/rmi.h |   2 +
> >  9 files changed, 670 insertions(+), 31 deletions(-)
> >  create mode 100644 drivers/input/rmi4/rmi_f34.c
> >  create mode 100644 drivers/input/rmi4/rmi_f34.h
> > 
> > diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> > index 8cbd362..9a24867 100644
> > --- a/drivers/input/rmi4/Kconfig
> > +++ b/drivers/input/rmi4/Kconfig
> > @@ -74,6 +74,17 @@ config RMI4_F30
> >   Function 30 provides GPIO and LED support for RMI4 devices. This
> >   includes support for buttons on TouchPads and ClickPads.
> >  
> > +config RMI4_F34
> > +   bool "RMI4 Function 34 (Device reflash)"
> > +   depends on RMI4_CORE
> > +   select FW_LOADER
> > +   help
> > + Say Y here if you want to add support for RMI4 function 34.
> > +
> > + Function 34 provides support for upgrading the firmware on the RMI4
> > + device via the firmware loader interface. This is triggered using a
> > + sysfs attribute.
> > +
> >  config RMI4_F54
> > bool "RMI4 Function 54 (Analog diagnostics)"
> > depends on RMI4_CORE
> > diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
> > index a6e2752..0250abf 100644
> > --- a/drivers/input/rmi4/Makefile
> > +++ b/drivers/input/rmi4/Makefile
> > @@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
> >  rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
> >  rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
> >  rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
> > +rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
> >  rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
> >  
> >  # Transports
> > diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
> > index 84b3212..ef7a662 100644
> > --- a/drivers/input/rmi4/rmi_bus.c
> > +++ b/drivers/input/rmi4/rmi_bus.c
> > @@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
> >  #ifdef CONFIG_RMI4_F30
> > _f30_handler,
> >  #endif
> > +#ifdef CONFIG_RMI4_F34
> > +   _f34_handler,
> > +#endif
> >  #ifdef CONFIG_RMI4_F54
> > _f54_handler,
> >  #endif
> > diff --git a/drivers/input/rmi4/rmi_driver.c 
> > b/drivers/input/rmi4/rmi_driver.c
> > index 4f8d197..2b17d8c 100644
> > --- a/drivers/input/rmi4/rmi_driver.c
> > +++ b/drivers/input/rmi4/rmi_driver.c
> > @@ -35,14 +35,24 @@
> >  #define RMI_DEVICE_RESET_CMD   0x01
> >  #define DEFAULT_RESET_DELAY_MS 100
> >  
> > -static void rmi_free_function_list(struct rmi_device *rmi_dev)
> > +void rmi_free_function_list(struct rmi_device *rmi_dev)
> >  {
> > struct rmi_function *fn, *tmp;
> > struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
> >  
> > rmi_dbg(RMI_DEBUG_CORE, _dev->dev, "Freeing function list\n");
> >  
> > +   mutex_lock(>irq_mutex);
> 
> Sorry for coming late in the party, but now that I am rebasing my
> patches on top of Dmitry's branch, I realise that the mutex lock/unlock
> operations are just wrong now.
> 
> irq_mutex used to protect the irq_mask of struct rmi_driver_data and
> where only used sparsely by the .config call during reset. It was also
> used by rmi_process_interrupt_requests() in the IRQ handler, but the
> chances of the conflict where low. Side note, this should be a spinlock
> given that it can be called in an interrupt context.

Ack

> But with this patch, the mutex now serves as a barrier for IRQs. It is
> now taken by a lot of functions that can stall a lot, and so the IRQ
> will not be happy to be put to sleep.
> 
> Looking at the code, I realise that we should be able to avoid the whole
> locks by the firmware update if we simply disable/enable the interrupts
> before attempting the firmware update (in rmi_firmware_update()).
> 
> If you agree with the general idea, I can revert those locks and simply
> call enable_irq/disable_irq in a following patch.

I don't believe the firmware update will work without the interrupts
being enabled - it uses a completion:

http://git.kernel.org/cgit/linux/kernel/git/dtor/input.git/tree/drivers/input/rmi4/rmi_f34.c?h=synaptics-rmi4#n103

I would suggest that if this is a problem, we can change the F34 to not
use the interrupt and poll instead?

cheers

Nick


Re: [PATCH v6 1/2] Input: synaptics-rmi4 - add support for F34 device reflash

2016-11-23 Thread Nick Dyer
On Wed, Nov 23, 2016 at 12:20:41PM +0100, Benjamin Tissoires wrote:
> On Nov 20 2016 or thereabouts, Nick Dyer wrote:
> > Add support for updating firmware, triggered by a sysfs attribute.
> > 
> > This patch has been tested on Synaptics S7300.
> > 
> > Signed-off-by: Nick Dyer 
> > Tested-by: Chris Healy 
> > ---
> >  drivers/input/rmi4/Kconfig  |  11 +
> >  drivers/input/rmi4/Makefile |   1 +
> >  drivers/input/rmi4/rmi_bus.c|   3 +
> >  drivers/input/rmi4/rmi_driver.c | 105 ++---
> >  drivers/input/rmi4/rmi_driver.h |  24 ++
> >  drivers/input/rmi4/rmi_f01.c|   6 +
> >  drivers/input/rmi4/rmi_f34.c| 481 
> > 
> >  drivers/input/rmi4/rmi_f34.h|  68 ++
> >  include/linux/rmi.h |   2 +
> >  9 files changed, 670 insertions(+), 31 deletions(-)
> >  create mode 100644 drivers/input/rmi4/rmi_f34.c
> >  create mode 100644 drivers/input/rmi4/rmi_f34.h
> > 
> > diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> > index 8cbd362..9a24867 100644
> > --- a/drivers/input/rmi4/Kconfig
> > +++ b/drivers/input/rmi4/Kconfig
> > @@ -74,6 +74,17 @@ config RMI4_F30
> >   Function 30 provides GPIO and LED support for RMI4 devices. This
> >   includes support for buttons on TouchPads and ClickPads.
> >  
> > +config RMI4_F34
> > +   bool "RMI4 Function 34 (Device reflash)"
> > +   depends on RMI4_CORE
> > +   select FW_LOADER
> > +   help
> > + Say Y here if you want to add support for RMI4 function 34.
> > +
> > + Function 34 provides support for upgrading the firmware on the RMI4
> > + device via the firmware loader interface. This is triggered using a
> > + sysfs attribute.
> > +
> >  config RMI4_F54
> > bool "RMI4 Function 54 (Analog diagnostics)"
> > depends on RMI4_CORE
> > diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
> > index a6e2752..0250abf 100644
> > --- a/drivers/input/rmi4/Makefile
> > +++ b/drivers/input/rmi4/Makefile
> > @@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
> >  rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
> >  rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
> >  rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
> > +rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
> >  rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
> >  
> >  # Transports
> > diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
> > index 84b3212..ef7a662 100644
> > --- a/drivers/input/rmi4/rmi_bus.c
> > +++ b/drivers/input/rmi4/rmi_bus.c
> > @@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
> >  #ifdef CONFIG_RMI4_F30
> > _f30_handler,
> >  #endif
> > +#ifdef CONFIG_RMI4_F34
> > +   _f34_handler,
> > +#endif
> >  #ifdef CONFIG_RMI4_F54
> > _f54_handler,
> >  #endif
> > diff --git a/drivers/input/rmi4/rmi_driver.c 
> > b/drivers/input/rmi4/rmi_driver.c
> > index 4f8d197..2b17d8c 100644
> > --- a/drivers/input/rmi4/rmi_driver.c
> > +++ b/drivers/input/rmi4/rmi_driver.c
> > @@ -35,14 +35,24 @@
> >  #define RMI_DEVICE_RESET_CMD   0x01
> >  #define DEFAULT_RESET_DELAY_MS 100
> >  
> > -static void rmi_free_function_list(struct rmi_device *rmi_dev)
> > +void rmi_free_function_list(struct rmi_device *rmi_dev)
> >  {
> > struct rmi_function *fn, *tmp;
> > struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
> >  
> > rmi_dbg(RMI_DEBUG_CORE, _dev->dev, "Freeing function list\n");
> >  
> > +   mutex_lock(>irq_mutex);
> 
> Sorry for coming late in the party, but now that I am rebasing my
> patches on top of Dmitry's branch, I realise that the mutex lock/unlock
> operations are just wrong now.
> 
> irq_mutex used to protect the irq_mask of struct rmi_driver_data and
> where only used sparsely by the .config call during reset. It was also
> used by rmi_process_interrupt_requests() in the IRQ handler, but the
> chances of the conflict where low. Side note, this should be a spinlock
> given that it can be called in an interrupt context.

Ack

> But with this patch, the mutex now serves as a barrier for IRQs. It is
> now taken by a lot of functions that can stall a lot, and so the IRQ
> will not be happy to be put to sleep.
> 
> Looking at the code, I realise that we should be able to avoid the whole
> locks by the firmware update if we simply disable/enable the interrupts
> before attempting the firmware update (in rmi_firmware_update()).
> 
> If you agree with the general idea, I can revert those locks and simply
> call enable_irq/disable_irq in a following patch.

I don't believe the firmware update will work without the interrupts
being enabled - it uses a completion:

http://git.kernel.org/cgit/linux/kernel/git/dtor/input.git/tree/drivers/input/rmi4/rmi_f34.c?h=synaptics-rmi4#n103

I would suggest that if this is a problem, we can change the F34 to not
use the interrupt and poll instead?

cheers

Nick


Re: [PATCH v6 2/2] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-11-23 Thread Nick Dyer
On Tue, Nov 22, 2016 at 05:51:11PM -0800, Dmitry Torokhov wrote:
> On Sun, Nov 20, 2016 at 07:04:02PM +0000, Nick Dyer wrote:
> > +   /* query 7 */
> > +   unsigned char f34_query7_b0:1;
> > +   unsigned char has_bootloader:1;
> > +   unsigned char has_device_config:1;
> > +   unsigned char has_flash_config:1;
> > +   unsigned char has_manufacturing_block:1;
> > +   unsigned char has_guest_serialization:1;
> > +   unsigned char has_global_parameters:1;
> > +   unsigned char has_core_code:1;
> > +   unsigned char has_core_config:1;
> > +   unsigned char has_guest_code:1;
> > +   unsigned char has_display_config:1;
> > +   unsigned char f34_query7_b11__15:5;
> > +   unsigned char f34_query7_b16__23;
> > +   unsigned char f34_query7_b24__31;
> 
> I see bitfields and I think this is not going to work on big endian
> arches because unfortunately they "fill" the bytes with bits in opposite
> order.
> 
> We had to rework old Unixsphere code to get rid of bitfields for on-wire
> data; this seems to be coming from that code base as well and so needs
> to be reworked too.

Hi Dmitry-

Thanks - that makes sense. I will rework this bit to remove the
bitfields.

cheers

Nick


Re: [PATCH v6 2/2] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-11-23 Thread Nick Dyer
On Tue, Nov 22, 2016 at 05:51:11PM -0800, Dmitry Torokhov wrote:
> On Sun, Nov 20, 2016 at 07:04:02PM +0000, Nick Dyer wrote:
> > +   /* query 7 */
> > +   unsigned char f34_query7_b0:1;
> > +   unsigned char has_bootloader:1;
> > +   unsigned char has_device_config:1;
> > +   unsigned char has_flash_config:1;
> > +   unsigned char has_manufacturing_block:1;
> > +   unsigned char has_guest_serialization:1;
> > +   unsigned char has_global_parameters:1;
> > +   unsigned char has_core_code:1;
> > +   unsigned char has_core_config:1;
> > +   unsigned char has_guest_code:1;
> > +   unsigned char has_display_config:1;
> > +   unsigned char f34_query7_b11__15:5;
> > +   unsigned char f34_query7_b16__23;
> > +   unsigned char f34_query7_b24__31;
> 
> I see bitfields and I think this is not going to work on big endian
> arches because unfortunately they "fill" the bytes with bits in opposite
> order.
> 
> We had to rework old Unixsphere code to get rid of bitfields for on-wire
> data; this seems to be coming from that code base as well and so needs
> to be reworked too.

Hi Dmitry-

Thanks - that makes sense. I will rework this bit to remove the
bitfields.

cheers

Nick


[PATCH v6 1/2] Input: synaptics-rmi4 - add support for F34 device reflash

2016-11-20 Thread Nick Dyer
Add support for updating firmware, triggered by a sysfs attribute.

This patch has been tested on Synaptics S7300.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Chris Healy <cphe...@gmail.com>
---
 drivers/input/rmi4/Kconfig  |  11 +
 drivers/input/rmi4/Makefile |   1 +
 drivers/input/rmi4/rmi_bus.c|   3 +
 drivers/input/rmi4/rmi_driver.c | 105 ++---
 drivers/input/rmi4/rmi_driver.h |  24 ++
 drivers/input/rmi4/rmi_f01.c|   6 +
 drivers/input/rmi4/rmi_f34.c| 481 
 drivers/input/rmi4/rmi_f34.h|  68 ++
 include/linux/rmi.h |   2 +
 9 files changed, 670 insertions(+), 31 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34.c
 create mode 100644 drivers/input/rmi4/rmi_f34.h

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index 8cbd362..9a24867 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -74,6 +74,17 @@ config RMI4_F30
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
 
+config RMI4_F34
+   bool "RMI4 Function 34 (Device reflash)"
+   depends on RMI4_CORE
+   select FW_LOADER
+   help
+ Say Y here if you want to add support for RMI4 function 34.
+
+ Function 34 provides support for upgrading the firmware on the RMI4
+ device via the firmware loader interface. This is triggered using a
+ sysfs attribute.
+
 config RMI4_F54
bool "RMI4 Function 54 (Analog diagnostics)"
depends on RMI4_CORE
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index a6e2752..0250abf 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index 84b3212..ef7a662 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F34
+   _f34_handler,
+#endif
 #ifdef CONFIG_RMI4_F54
_f54_handler,
 #endif
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 4f8d197..2b17d8c 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -35,14 +35,24 @@
 #define RMI_DEVICE_RESET_CMD   0x01
 #define DEFAULT_RESET_DELAY_MS 100
 
-static void rmi_free_function_list(struct rmi_device *rmi_dev)
+void rmi_free_function_list(struct rmi_device *rmi_dev)
 {
struct rmi_function *fn, *tmp;
struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
 
rmi_dbg(RMI_DEBUG_CORE, _dev->dev, "Freeing function list\n");
 
+   mutex_lock(>irq_mutex);
+
+   devm_kfree(_dev->dev, data->irq_memory);
+   data->irq_memory = NULL;
+   data->irq_status = NULL;
+   data->fn_irq_bits = NULL;
+   data->current_irq_mask = NULL;
+   data->new_irq_mask = NULL;
+
data->f01_container = NULL;
+   data->f34_container = NULL;
 
/* Doing it in the reverse order so F01 will be removed last */
list_for_each_entry_safe_reverse(fn, tmp,
@@ -50,7 +60,10 @@ static void rmi_free_function_list(struct rmi_device 
*rmi_dev)
list_del(>node);
rmi_unregister_function(fn);
}
+
+   mutex_unlock(>irq_mutex);
 }
+EXPORT_SYMBOL_GPL(rmi_free_function_list);
 
 static int reset_one_function(struct rmi_function *fn)
 {
@@ -147,24 +160,25 @@ static int rmi_process_interrupt_requests(struct 
rmi_device *rmi_dev)
if (!data)
return 0;
 
+   mutex_lock(>irq_mutex);
+   if (!data->irq_status || !data->f01_container) {
+   mutex_unlock(>irq_mutex);
+   return 0;
+   }
+
if (!rmi_dev->xport->attn_data) {
error = rmi_read_block(rmi_dev,
data->f01_container->fd.data_base_addr + 1,
data->irq_status, data->num_of_irq_regs);
if (error < 0) {
dev_err(dev, "Failed to read irqs, code=%d\n", error);
+   mutex_unlock(>irq_mutex);
return error;
}
}
 
-   mutex_lock(>irq_mutex);
bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask,
   data->irq_count);
-   /*
-* At this point, irq_status has all bits that are set in

[PATCH v6 2/2] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-11-20 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer <n...@shmanahar.org>
Tested-by: Chris Healy <cphe...@gmail.com>
---
 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   37 +-
 drivers/input/rmi4/rmi_f34.h|  327 -
 drivers/input/rmi4/rmi_f34v7.c  | 1439 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1829 insertions(+), 34 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 0250abf..f187298 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,7 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 2b17d8c..ade26f2 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -527,7 +527,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -737,41 +737,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *irq_count = ctx;
+   int ret;
 
*irq_count += pdt->interrupt_source_count;
-   if (pdt->function_number == 0x01)
-   data->f01_bootloader_mode =
-   rmi_check_bootloader_mode(rmi_dev, pdt);
+
+   ret = rmi_check_bootloader_mode(rmi_dev, pdt);
+   if (ret < 0)
+   return ret;
 
return RMI_SCAN_CONTINUE;
 }
@@ -964,13 +972,15 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
 */
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__);
irq_count = 0;
+   data->bootloader_mode = false;
+
retval = rmi_scan_pdt(rmi_dev, _count, rmi_count_irqs);
if (retval < 0) {
dev_err(dev, "IRQ counting failed with code %d.\n", retval);
return retval;
}
 
-   if (data->f01_bootloader_mode)
+   if (data->bootloader_mode)
dev_warn(_dev->dev, "Device in bootloader mode.\n");
 
data->irq_count = irq_count;
diff --git a/drivers/

[PATCH v6 1/2] Input: synaptics-rmi4 - add support for F34 device reflash

2016-11-20 Thread Nick Dyer
Add support for updating firmware, triggered by a sysfs attribute.

This patch has been tested on Synaptics S7300.

Signed-off-by: Nick Dyer 
Tested-by: Chris Healy 
---
 drivers/input/rmi4/Kconfig  |  11 +
 drivers/input/rmi4/Makefile |   1 +
 drivers/input/rmi4/rmi_bus.c|   3 +
 drivers/input/rmi4/rmi_driver.c | 105 ++---
 drivers/input/rmi4/rmi_driver.h |  24 ++
 drivers/input/rmi4/rmi_f01.c|   6 +
 drivers/input/rmi4/rmi_f34.c| 481 
 drivers/input/rmi4/rmi_f34.h|  68 ++
 include/linux/rmi.h |   2 +
 9 files changed, 670 insertions(+), 31 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34.c
 create mode 100644 drivers/input/rmi4/rmi_f34.h

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index 8cbd362..9a24867 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -74,6 +74,17 @@ config RMI4_F30
  Function 30 provides GPIO and LED support for RMI4 devices. This
  includes support for buttons on TouchPads and ClickPads.
 
+config RMI4_F34
+   bool "RMI4 Function 34 (Device reflash)"
+   depends on RMI4_CORE
+   select FW_LOADER
+   help
+ Say Y here if you want to add support for RMI4 function 34.
+
+ Function 34 provides support for upgrading the firmware on the RMI4
+ device via the firmware loader interface. This is triggered using a
+ sysfs attribute.
+
 config RMI4_F54
bool "RMI4 Function 54 (Analog diagnostics)"
depends on RMI4_CORE
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index a6e2752..0250abf 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,6 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
index 84b3212..ef7a662 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -315,6 +315,9 @@ static struct rmi_function_handler *fn_handlers[] = {
 #ifdef CONFIG_RMI4_F30
_f30_handler,
 #endif
+#ifdef CONFIG_RMI4_F34
+   _f34_handler,
+#endif
 #ifdef CONFIG_RMI4_F54
_f54_handler,
 #endif
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 4f8d197..2b17d8c 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -35,14 +35,24 @@
 #define RMI_DEVICE_RESET_CMD   0x01
 #define DEFAULT_RESET_DELAY_MS 100
 
-static void rmi_free_function_list(struct rmi_device *rmi_dev)
+void rmi_free_function_list(struct rmi_device *rmi_dev)
 {
struct rmi_function *fn, *tmp;
struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
 
rmi_dbg(RMI_DEBUG_CORE, _dev->dev, "Freeing function list\n");
 
+   mutex_lock(>irq_mutex);
+
+   devm_kfree(_dev->dev, data->irq_memory);
+   data->irq_memory = NULL;
+   data->irq_status = NULL;
+   data->fn_irq_bits = NULL;
+   data->current_irq_mask = NULL;
+   data->new_irq_mask = NULL;
+
data->f01_container = NULL;
+   data->f34_container = NULL;
 
/* Doing it in the reverse order so F01 will be removed last */
list_for_each_entry_safe_reverse(fn, tmp,
@@ -50,7 +60,10 @@ static void rmi_free_function_list(struct rmi_device 
*rmi_dev)
list_del(>node);
rmi_unregister_function(fn);
}
+
+   mutex_unlock(>irq_mutex);
 }
+EXPORT_SYMBOL_GPL(rmi_free_function_list);
 
 static int reset_one_function(struct rmi_function *fn)
 {
@@ -147,24 +160,25 @@ static int rmi_process_interrupt_requests(struct 
rmi_device *rmi_dev)
if (!data)
return 0;
 
+   mutex_lock(>irq_mutex);
+   if (!data->irq_status || !data->f01_container) {
+   mutex_unlock(>irq_mutex);
+   return 0;
+   }
+
if (!rmi_dev->xport->attn_data) {
error = rmi_read_block(rmi_dev,
data->f01_container->fd.data_base_addr + 1,
data->irq_status, data->num_of_irq_regs);
if (error < 0) {
dev_err(dev, "Failed to read irqs, code=%d\n", error);
+   mutex_unlock(>irq_mutex);
return error;
}
}
 
-   mutex_lock(>irq_mutex);
bitmap_and(data->irq_status, data->irq_status, data->current_irq_mask,
   data->irq_count);
-   /*
-* At this point, irq_status has all bits that are set in the
-* interrupt status register and are

[PATCH v6 2/2] Input: synaptics-rmi4 - add support for F34 V7 bootloader

2016-11-20 Thread Nick Dyer
Port firmware update code from Samsung Galaxy S7 driver into
mainline framework.

This patch has been tested on Synaptics S7813.

Signed-off-by: Nick Dyer 
Tested-by: Chris Healy 
---
 drivers/input/rmi4/Makefile |2 +-
 drivers/input/rmi4/rmi_driver.c |   56 +-
 drivers/input/rmi4/rmi_f34.c|   37 +-
 drivers/input/rmi4/rmi_f34.h|  327 -
 drivers/input/rmi4/rmi_f34v7.c  | 1439 +++
 include/linux/rmi.h |2 +-
 6 files changed, 1829 insertions(+), 34 deletions(-)
 create mode 100644 drivers/input/rmi4/rmi_f34v7.c

diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 0250abf..f187298 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -7,7 +7,7 @@ rmi_core-$(CONFIG_RMI4_2D_SENSOR) += rmi_2d_sensor.o
 rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
 rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
 rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
-rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o
+rmi_core-$(CONFIG_RMI4_F34) += rmi_f34.o rmi_f34v7.o
 rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
 
 # Transports
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 2b17d8c..ade26f2 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -527,7 +527,7 @@ static int rmi_scan_pdt_page(struct rmi_device *rmi_dev,
else
*empty_pages = 0;
 
-   return (data->f01_bootloader_mode || *empty_pages >= 2) ?
+   return (data->bootloader_mode || *empty_pages >= 2) ?
RMI_SCAN_DONE : RMI_SCAN_CONTINUE;
 }
 
@@ -737,41 +737,49 @@ bool rmi_register_desc_has_subpacket(const struct 
rmi_register_desc_item *item,
subpacket) == subpacket;
 }
 
-/* Indicates that flash programming is enabled (bootloader mode). */
-#define RMI_F01_STATUS_BOOTLOADER(status)  (!!((status) & 0x40))
-
-/*
- * Given the PDT entry for F01, read the device status register to determine
- * if we're stuck in bootloader mode or not.
- *
- */
 static int rmi_check_bootloader_mode(struct rmi_device *rmi_dev,
 const struct pdt_entry *pdt)
 {
-   int error;
-   u8 device_status;
+   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
+   int ret;
+   u8 status;
 
-   error = rmi_read(rmi_dev, pdt->data_base_addr + pdt->page_start,
-_status);
-   if (error) {
-   dev_err(_dev->dev,
-   "Failed to read device status: %d.\n", error);
-   return error;
+   if (pdt->function_number == 0x34 && pdt->function_version > 1) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F34 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(7))
+   data->bootloader_mode = true;
+   } else if (pdt->function_number == 0x01) {
+   ret = rmi_read(rmi_dev, pdt->data_base_addr, );
+   if (ret) {
+   dev_err(_dev->dev,
+   "Failed to read F01 status: %d.\n", ret);
+   return ret;
+   }
+
+   if (status & BIT(6))
+   data->bootloader_mode = true;
}
 
-   return RMI_F01_STATUS_BOOTLOADER(device_status);
+   return 0;
 }
 
 static int rmi_count_irqs(struct rmi_device *rmi_dev,
 void *ctx, const struct pdt_entry *pdt)
 {
-   struct rmi_driver_data *data = dev_get_drvdata(_dev->dev);
int *irq_count = ctx;
+   int ret;
 
*irq_count += pdt->interrupt_source_count;
-   if (pdt->function_number == 0x01)
-   data->f01_bootloader_mode =
-   rmi_check_bootloader_mode(rmi_dev, pdt);
+
+   ret = rmi_check_bootloader_mode(rmi_dev, pdt);
+   if (ret < 0)
+   return ret;
 
return RMI_SCAN_CONTINUE;
 }
@@ -964,13 +972,15 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
 */
rmi_dbg(RMI_DEBUG_CORE, dev, "%s: Counting IRQs.\n", __func__);
irq_count = 0;
+   data->bootloader_mode = false;
+
retval = rmi_scan_pdt(rmi_dev, _count, rmi_count_irqs);
if (retval < 0) {
dev_err(dev, "IRQ counting failed with code %d.\n", retval);
return retval;
}
 
-   if (data->f01_bootloader_mode)
+   if (data->bootloader_mode)
dev_warn(_dev->dev, "Device in bootloader mode.\n");
 
data->irq_count = irq_count;
diff --git a/drivers/input/rmi4/rmi_f34.c b/drivers/input/rmi4/rmi_f34.c
index 

[PATCH v6 0/2] Input: synaptics-rmi4 - F34 device reflash support

2016-11-20 Thread Nick Dyer
Hi Dmitry-

Please find an updated set of patches to add F34 firmware update to the RMI4
driver.

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy

cheers

Nick



[PATCH v6 0/2] Input: synaptics-rmi4 - F34 device reflash support

2016-11-20 Thread Nick Dyer
Hi Dmitry-

Please find an updated set of patches to add F34 firmware update to the RMI4
driver.

Changes in v6:
- Properly free irq_memory in rmi_free_function_list()
- Split out the sysfs changes for now
- Various coding style improvements to the V7 patch (now checkpatch clean)

Changes in v5:
- Improve split between for different versions (req. Bjorn Andersson)
- Address a couple of kbuild test robot issues
- Fix a bug with configuration ID on V7

Changes in v4:
- Add support for v7 bootloaders and fix numerous issues
- Add sysfs attributes for retrieving various hardware IDs
- Add a couple of debug lines to core

Changes in v3:
- Only attempt to flash on F34 V0 (later versions have different
  register map)

Changes in v2:
- Resolved reliability issues with locking and teardown/re-probe
- Add #ifdefs for CONFIG_RMI4_F34 in rmi_driver.c
- Slightly improve debug
- Tested by Chris Healy

cheers

Nick



Re: [PATCH v2 2/2] Input: synaptics-rmi4 - Propagate correct number of rx and tx electrodes to F54

2016-11-15 Thread Nick Dyer
On Mon, Nov 14, 2016 at 09:39:38PM -0800, Guenter Roeck wrote:
> F54 diagnostics report functions provide data based on the number of
> enabled rx and tx electrodes, which is not identical to the number of
> electrodes reported with F54:Query0 and F54:Query1. Those values report
> the number of supported electrodes, not the number of enabled electrodes.
> The number of enabled electrodes can be determined by analyzing F55:Ctrl1
> (sensor receiver assignment) and F55:Ctrl2 (sensor transmitter assignment).
> 
> Propagate the number of enabled electrodes from F55 to F54 to avoid
> corrupted output if not all electrodes are enabled.
> 
> Fixes: 3a762dbd5347 ("[media] Input: synaptics-rmi4 - add support for F54 
> ...")
> Cc: Nick Dyer <n...@shmanahar.org>
> Cc: Andrew Duggan <adug...@synaptics.com>
> Cc: Chris Healy <cphe...@gmail.com>
> Signed-off-by: Guenter Roeck <li...@roeck-us.net>

Tested-by: Nick Dyer <n...@shmanahar.org>

> ---
> v2: Update Fixes: sha
> 
>  drivers/input/rmi4/Kconfig   |  1 +
>  drivers/input/rmi4/rmi_f54.c | 14 ++
>  drivers/input/rmi4/rmi_f55.c |  7 +++
>  include/linux/rmi.h  |  3 +++
>  4 files changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> index 11ede43c9936..d7129928cde6 100644
> --- a/drivers/input/rmi4/Kconfig
> +++ b/drivers/input/rmi4/Kconfig
> @@ -67,6 +67,7 @@ config RMI4_F54
>   depends on RMI4_CORE
>   depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m)
>   select VIDEOBUF2_VMALLOC
> + select RMI4_F55
>   help
> Say Y here if you want to add support for RMI4 function 54
>  
> diff --git a/drivers/input/rmi4/rmi_f54.c b/drivers/input/rmi4/rmi_f54.c
> index cf805b960866..9cb3aa733f0f 100644
> --- a/drivers/input/rmi4/rmi_f54.c
> +++ b/drivers/input/rmi4/rmi_f54.c
> @@ -216,8 +216,10 @@ static int rmi_f54_request_report(struct rmi_function 
> *fn, u8 report_type)
>  
>  static size_t rmi_f54_get_report_size(struct f54_data *f54)
>  {
> - u8 rx = f54->num_rx_electrodes ? : f54->num_rx_electrodes;
> - u8 tx = f54->num_tx_electrodes ? : f54->num_tx_electrodes;
> + struct rmi_device *rmi_dev = f54->fn->rmi_dev;
> + struct rmi_driver_data *drv_data = dev_get_drvdata(_dev->dev);
> + u8 rx = drv_data->num_rx_electrodes ? : f54->num_rx_electrodes;
> + u8 tx = drv_data->num_tx_electrodes ? : f54->num_tx_electrodes;
>   size_t size;
>  
>   switch (rmi_f54_get_reptype(f54, f54->input)) {
> @@ -401,6 +403,10 @@ static int rmi_f54_vidioc_enum_input(struct file *file, 
> void *priv,
>  
>  static int rmi_f54_set_input(struct f54_data *f54, unsigned int i)
>  {
> + struct rmi_device *rmi_dev = f54->fn->rmi_dev;
> + struct rmi_driver_data *drv_data = dev_get_drvdata(_dev->dev);
> + u8 rx = drv_data->num_rx_electrodes ? : f54->num_rx_electrodes;
> + u8 tx = drv_data->num_tx_electrodes ? : f54->num_tx_electrodes;
>   struct v4l2_pix_format *f = >format;
>   enum rmi_f54_report_type reptype;
>   int ret;
> @@ -415,8 +421,8 @@ static int rmi_f54_set_input(struct f54_data *f54, 
> unsigned int i)
>  
>   f54->input = i;
>  
> - f->width = f54->num_rx_electrodes;
> - f->height = f54->num_tx_electrodes;
> + f->width = rx;
> + f->height = tx;
>   f->field = V4L2_FIELD_NONE;
>   f->colorspace = V4L2_COLORSPACE_RAW;
>   f->bytesperline = f->width * sizeof(u16);
> diff --git a/drivers/input/rmi4/rmi_f55.c b/drivers/input/rmi4/rmi_f55.c
> index 2d221cc97391..37390ca6a924 100644
> --- a/drivers/input/rmi4/rmi_f55.c
> +++ b/drivers/input/rmi4/rmi_f55.c
> @@ -38,6 +38,8 @@ struct f55_data {
>  
>  static int rmi_f55_detect(struct rmi_function *fn)
>  {
> + struct rmi_device *rmi_dev = fn->rmi_dev;
> + struct rmi_driver_data *drv_data = dev_get_drvdata(_dev->dev);
>   struct f55_data *f55;
>   int error;
>  
> @@ -57,6 +59,9 @@ static int rmi_f55_detect(struct rmi_function *fn)
>   f55->cfg_num_rx_electrodes = f55->num_rx_electrodes;
>   f55->cfg_num_tx_electrodes = f55->num_rx_electrodes;
>  
> + drv_data->num_rx_electrodes = f55->cfg_num_rx_electrodes;
> + drv_data->num_tx_electrodes = f55->cfg_num_rx_electrodes;
> +
>   if (f55->qry[F55_PHYS_CHAR_OFFSET] & F55_CAP_SENSOR_ASSIGN) {
>   int i, total;
>   u8 buf[256];
> @@ -78,6 +83,7 @@ static int rmi_f55_detect(struct rmi_function *fn)
>   total

Re: [PATCH v2 1/2] Input: synaptics-rmi4 - add support for F55 sensor tuning

2016-11-15 Thread Nick Dyer
On Mon, Nov 14, 2016 at 09:39:37PM -0800, Guenter Roeck wrote:
> Sensor tuning support is needed to determine the number of enabled
> tx and rx electrodes for use in F54 functions.
> 
> The number of enabled electrodes is not identical to the total number
> of electrodes as reported with F55:Query0 and F55:Query1. It has to be
> calculated by analyzing F55:Ctrl1 (sensor receiver assignment) and
> F55:Ctrl2 (sensor transmitter assignment).
> 
> Support for additional sensor tuning functions may be added later.
> 
> Fixes: 3a762dbd5347 ("[media] Input: synaptics-rmi4 - add support for F54 
> ...")
> Signed-off-by: Guenter Roeck <li...@roeck-us.net>

Hi Guenter-

I've tested this patch on s7813 and it works correctly.

Tested-by: Nick Dyer <n...@shmanahar.org>

> ---
> v2: Drop unnecessary include files
> Only read required number of query elements
> Added Fixes: tag (both patch 1 and 2 are needed)
> 
>  drivers/input/rmi4/Kconfig  |   9 +++
>  drivers/input/rmi4/Makefile |   1 +
>  drivers/input/rmi4/rmi_bus.c|   3 +
>  drivers/input/rmi4/rmi_driver.h |   1 +
>  drivers/input/rmi4/rmi_f55.c| 124 
> 
>  5 files changed, 138 insertions(+)
>  create mode 100644 drivers/input/rmi4/rmi_f55.c
> 
> diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
> index 4c8a55857e00..11ede43c9936 100644
> --- a/drivers/input/rmi4/Kconfig
> +++ b/drivers/input/rmi4/Kconfig
> @@ -72,3 +72,12 @@ config RMI4_F54
>  
> Function 54 provides access to various diagnostic features in certain
> RMI4 touch sensors.
> +
> +config RMI4_F55
> + bool "RMI4 Function 55 (Sensor tuning)"
> + depends on RMI4_CORE
> + help
> +   Say Y here if you want to add support for RMI4 function 55
> +
> +   Function 55 provides access to the RMI4 touch sensor tuning
> +   mechanism.
> diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
> index 0bafc8502c4b..96f8e0c21e3b 100644
> --- a/drivers/input/rmi4/Makefile
> +++ b/drivers/input/rmi4/Makefile
> @@ -8,6 +8,7 @@ rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.o
>  rmi_core-$(CONFIG_RMI4_F12) += rmi_f12.o
>  rmi_core-$(CONFIG_RMI4_F30) += rmi_f30.o
>  rmi_core-$(CONFIG_RMI4_F54) += rmi_f54.o
> +rmi_core-$(CONFIG_RMI4_F55) += rmi_f55.o
>  
>  # Transports
>  obj-$(CONFIG_RMI4_I2C) += rmi_i2c.o
> diff --git a/drivers/input/rmi4/rmi_bus.c b/drivers/input/rmi4/rmi_bus.c
> index ef8c747c35e7..82b7d4960858 100644
> --- a/drivers/input/rmi4/rmi_bus.c
> +++ b/drivers/input/rmi4/rmi_bus.c
> @@ -314,6 +314,9 @@ static struct rmi_function_handler *fn_handlers[] = {
>  #ifdef CONFIG_RMI4_F54
>   _f54_handler,
>  #endif
> +#ifdef CONFIG_RMI4_F55
> + _f55_handler,
> +#endif
>  };
>  
>  static void __rmi_unregister_function_handlers(int start_idx)
> diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
> index 8dfbebe9bf86..a65cf70f61e2 100644
> --- a/drivers/input/rmi4/rmi_driver.h
> +++ b/drivers/input/rmi4/rmi_driver.h
> @@ -103,4 +103,5 @@ extern struct rmi_function_handler rmi_f11_handler;
>  extern struct rmi_function_handler rmi_f12_handler;
>  extern struct rmi_function_handler rmi_f30_handler;
>  extern struct rmi_function_handler rmi_f54_handler;
> +extern struct rmi_function_handler rmi_f55_handler;
>  #endif
> diff --git a/drivers/input/rmi4/rmi_f55.c b/drivers/input/rmi4/rmi_f55.c
> new file mode 100644
> index ..2d221cc97391
> --- /dev/null
> +++ b/drivers/input/rmi4/rmi_f55.c
> @@ -0,0 +1,124 @@
> +/*
> + * Copyright (c) 2012-2015 Synaptics Incorporated
> + * Copyright (C) 2016 Zodiac Inflight Innovations
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published 
> by
> + * the Free Software Foundation.
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include "rmi_driver.h"
> +
> +#define F55_NAME "rmi4_f55"
> +
> +/* F55 data offsets */
> +#define F55_NUM_RX_OFFSET0
> +#define F55_NUM_TX_OFFSET1
> +#define F55_PHYS_CHAR_OFFSET 2
> +
> +/* Only read required query registers */
> +#define F55_QUERY_LEN3
> +
> +/* F55 capabilities */
> +#define F55_CAP_SENSOR_ASSIGNBIT(0)
> +
> +struct f55_data {
> + struct rmi_function *fn;
> +
> + u8 qry[F55_QUERY_LEN];
> + u8 num_rx_electrodes;
> + u8 cfg_num_rx_electrodes;
> + u8 num_tx_electrodes;
> + u8 cfg_num_tx_electrodes;
> +};
> +
> +static int rmi_f55_detect(struct rmi_functio

  1   2   3   4   5   6   7   8   9   10   >