Re: [PATCH] touchscreen: sun4i-ts: Really fix A10 temperature reporting

2015-06-23 Thread m . silentcreek
Hi Hans,

is it possible that this patch (and the parent commit Input: sun4i-ts - allow 
controlling filter and sensitivity via DT) has quite an adversial effect on 
other boards than the ones tested?

On my Lemaker Bananapi the temperature is now being reported as somwhere 
between -15°C to -10°C with the latest Kernel 4.1.0. These negative values are 
obviously way off. On Kernel 4.0.5 the temperature reading was usually around 
40°C. While that might not have been accurate either, it was at least plausible.

Given that there is no Documentation and things seem quite board-specific, I 
really don't know how this could be improved, so I can merely report my 
observation.

Kind regards,

Timo 


Am Montag, 9. März 2015 10:38:02 UTC+1 schrieb Hans de Goede:
 The commit titled:
 touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
 contains a math error, the offset it uses is in degrees, but the actual code
 applies the offset before multiplying by stepsize :|
 
 Given that this is rather backwards (every math course ever thought applies
 the multiplication before the offset for linear functions), this commit
 fixes things by changing the code applying the offset to do the logical
 thing, adjusting the offset for the other models accordingly.
 
 This has been tested on an A10, A13, A20 and A31 to make sure everything 
 really
 is correct now.
 
 Signed-off-by: Hans de Goede hdego...@redhat.com
 ---
 Note if possible this commit should be squashed into the original
 touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
 commit as a fixup.
 ---
  drivers/input/touchscreen/sun4i-ts.c | 14 +++---
  1 file changed, 7 insertions(+), 7 deletions(-)
 
 diff --git a/drivers/input/touchscreen/sun4i-ts.c 
 b/drivers/input/touchscreen/sun4i-ts.c
 index 66ccd5a..178d2ef 100644
 --- a/drivers/input/touchscreen/sun4i-ts.c
 +++ b/drivers/input/touchscreen/sun4i-ts.c
 @@ -193,7 +193,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data *ts, 
 long *temp)
   if (ts-temp_data == -1)
   return -EAGAIN;
  
 - *temp = (ts-temp_data - ts-temp_offset) * ts-temp_step;
 + *temp = ts-temp_data * ts-temp_step - ts-temp_offset;
  
   return 0;
  }
 @@ -255,17 +255,17 @@ static int sun4i_ts_probe(struct platform_device *pdev)
   ts-ignore_fifo_data = true;
   ts-temp_data = -1;
   if (of_device_is_compatible(np, allwinner,sun6i-a31-ts)) {
 - /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
 - ts-temp_offset = 1626;
 + /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
 + ts-temp_offset = 271000;
   ts-temp_step = 167;
   } else if (of_device_is_compatible(np, allwinner,sun4i-a10-ts)) {
   /*
* The A10 temperature sensor has quite a wide spread, these
* parameters are based on the averaging of the calibration
* results of 4 completely different boards, with a spread of
 -  * temp_step from 96 - 170 and temp_offset from 1758 - 3310.
 +  * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
*/
 - ts-temp_offset = 2570;
 + ts-temp_offset = 257000;
   ts-temp_step = 133;
   } else {
   /*
 @@ -273,13 +273,13 @@ static int sun4i_ts_probe(struct platform_device *pdev)
* the temperature. The formula used here is from the AXP209,
* which is designed by X-Powers, an affiliate of Allwinner:
*
 -  * temperature = -144.7 + (value * 0.1)
 +  * temperature (C) = (value * 0.1) - 144.7
*
* Allwinner does not have any documentation whatsoever for
* this hardware. Moreover, it is claimed that the sensor
* is inaccurate and cannot work properly.
*/
 - ts-temp_offset = 1447;
 + ts-temp_offset = 144700;
   ts-temp_step = 100;
   }
  
 -- 
 2.3.1



Re: [PATCH v2 4/8] input: goodix: reset device at init

2015-06-23 Thread Octavian Purdila
On Tue, Jun 23, 2015 at 5:12 PM, Bastien Nocera had...@hadess.net wrote:

 On Tue, 2015-06-23 at 13:23 +, Tirdea, Irina wrote:
 
   -Original Message-
   From: linux-input-ow...@vger.kernel.org [mailto:
   linux-input-ow...@vger.kernel.org] On Behalf Of Bastien Nocera
   Sent: 09 June, 2015 18:53
   To: Tirdea, Irina
   Cc: Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org;
   devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Rob
   Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
   Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init
  
   On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:
On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:
 After power on, it is recommended that the driver resets the
 device.
 The reset procedure timing is described in the datasheet and is
 used
 at device init (before writing device configuration) and
 for power management. It is a sequence of setting the interrupt
 and reset pins high/low at specific timing intervals. This
 procedure
 also includes setting the slave address to the one specified in
 the
 ACPI/device tree.
   
This breaks the touchscreen on my Onda v975w:
[  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020
[  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset
GPIO:
-16
[  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with
error
-16
   
This is the DSDT for that device:
https://bugzilla.kernel.org/attachment.cgi?id=149331
  
 
  Oops. That's right - I am using named interrupts which are available
  only for ACPI 5.1, so
  devices already out there will not work.
 
  The problem here is that handling -ENOENT will not help. The gpio
  pins are declared in the
  ACPI DSDT, but are not named. The devm_gpiod_get API will look for
  the named interrupt
  first and fallback to searching by index if not found. Index will be
  0 in both cases, this is why
  the first call will succeed and the second will fail with -EBUSY.
 
  One way to handle this would be to use indexed gpio pins instead of
  named gpio pins:
  e.g. consider the first gpio pin to be the reset pin and the second
  to be the interrupt pin.
  This is used in other drivers as well, e.g. zforce_ts. The problem
  with this approach is that
  any devices that declare the gpio pins in reversed order in the DSDT
  will not work and give
  no warning (the pins will be requested successfully, but some of the
  functionality will not
  work). The DSDT mentioned in
  https://bugzilla.kernel.org/attachment.cgi?id=149331 lists
  the reset pin first, while I am working on some devices that declare
  the interrupt gpio pin
  first.
 
  Another way to handle this is to treat -EBUSY like -ENOENT and not
  use any functionality
  that depends on the gpio pins. Unfortunately, this means we will not
  have suspend, esd and
  custom configs even if the pins are connected on the board and
  available in ACPI(just not
  named).
 
  I would go with the first approach and document the order requested
  for the pins, but I would
  like to hear what you think first. Is there a better way to do this?
 
   (Note that this means that I haven't been able to test any
   following
   patches in that series than 4/8).
 
  Sure, that makes sense. The following patches depend on the gpio pins
  so they would not have
  worked either.

 We can apply quirks based on DMI information, so that devices with ACPI
 in different orders will work after applying a quirk (as long as
 there's a way to detect that it's in the wrong order, obviously).


I think even using the ACPI id (_HID) should be enough (at least in
the cases we know so far) to make the difference in how the pins are
used.
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/8] input: goodix: reset device at init

2015-06-23 Thread Bastien Nocera
On Tue, 2015-06-23 at 13:23 +, Tirdea, Irina wrote:
 
  -Original Message-
  From: linux-input-ow...@vger.kernel.org [mailto:
  linux-input-ow...@vger.kernel.org] On Behalf Of Bastien Nocera
  Sent: 09 June, 2015 18:53
  To: Tirdea, Irina
  Cc: Dmitry Torokhov; Mark Rutland; linux-input@vger.kernel.org; 
  devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Rob
  Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
  Subject: Re: [PATCH v2 4/8] input: goodix: reset device at init
  
  On Tue, 2015-06-09 at 17:34 +0200, Bastien Nocera wrote:
   On Mon, 2015-06-08 at 17:37 +0300, Irina Tirdea wrote:
After power on, it is recommended that the driver resets the
device.
The reset procedure timing is described in the datasheet and is
used
at device init (before writing device configuration) and
for power management. It is a sequence of setting the interrupt
and reset pins high/low at specific timing intervals. This
procedure
also includes setting the slave address to the one specified in 
the
ACPI/device tree.
   
   This breaks the touchscreen on my Onda v975w:
   [  239.732858] Goodix-TS i2c-GDIX1001:00: ID 9271, version: 1020
   [  239.732977] Goodix-TS i2c-GDIX1001:00: Failed to get reset 
   GPIO:
   -16
   [  239.736071] Goodix-TS: probe of i2c-GDIX1001:00 failed with 
   error
   -16
   
   This is the DSDT for that device:
   https://bugzilla.kernel.org/attachment.cgi?id=149331
  
 
 Oops. That's right - I am using named interrupts which are available 
 only for ACPI 5.1, so 
 devices already out there will not work.
 
 The problem here is that handling -ENOENT will not help. The gpio 
 pins are declared in the
 ACPI DSDT, but are not named. The devm_gpiod_get API will look for 
 the named interrupt
 first and fallback to searching by index if not found. Index will be 
 0 in both cases, this is why
 the first call will succeed and the second will fail with -EBUSY.
 
 One way to handle this would be to use indexed gpio pins instead of 
 named gpio pins:
 e.g. consider the first gpio pin to be the reset pin and the second 
 to be the interrupt pin.
 This is used in other drivers as well, e.g. zforce_ts. The problem 
 with this approach is that
 any devices that declare the gpio pins in reversed order in the DSDT 
 will not work and give
 no warning (the pins will be requested successfully, but some of the 
 functionality will not
 work). The DSDT mentioned in 
 https://bugzilla.kernel.org/attachment.cgi?id=149331 lists
 the reset pin first, while I am working on some devices that declare 
 the interrupt gpio pin
 first.
 
 Another way to handle this is to treat -EBUSY like -ENOENT and not 
 use any functionality
 that depends on the gpio pins. Unfortunately, this means we will not 
 have suspend, esd and
 custom configs even if the pins are connected on the board and 
 available in ACPI(just not
 named).
 
 I would go with the first approach and document the order requested 
 for the pins, but I would
 like to hear what you think first. Is there a better way to do this?
 
  (Note that this means that I haven't been able to test any 
  following
  patches in that series than 4/8).
 
 Sure, that makes sense. The following patches depend on the gpio pins 
 so they would not have
 worked either.

We can apply quirks based on DMI information, so that devices with ACPI
in different orders will work after applying a quirk (as long as
there's a way to detect that it's in the wrong order, obviously).

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH v2 5/8] input: goodix: write configuration data to device

2015-06-23 Thread Tirdea, Irina


 -Original Message-
 From: linux-input-ow...@vger.kernel.org 
 [mailto:linux-input-ow...@vger.kernel.org] On Behalf Of Dmitry Torokhov
 Sent: 09 June, 2015 21:14
 To: Tirdea, Irina
 Cc: Bastien Nocera; Mark Rutland; linux-input@vger.kernel.org; 
 devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Rob
 Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
 Subject: Re: [PATCH v2 5/8] input: goodix: write configuration data to device
 
 Hi Irina,
 

Hi Dmitry,

 On Mon, Jun 08, 2015 at 05:37:50PM +0300, Irina Tirdea wrote:
  Goodix devices can be configured by writing custom data to the device at
  init. The configuration data is read with request_firmware from
  goodix_id_cfg.bin, where id is the product id read from the device
  (e.g.: goodix_911_cfg.bin for Goodix GT911, goodix_9271_cfg.bin for
  GT9271).
 
  The configuration information has a specific format described in the Goodix
  datasheet. It includes X/Y resolution, maximum supported touch points,
  interrupt flags, various sesitivity factors and settings for advanced
  features (like gesture recognition).
 
  This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
  driver gt9xx.c for Android (publicly available in Android kernel
  trees for various devices).
 
 I am afraid that just using request_firmware() in probe() is not the
 best option as it may cause either errors or delays in
 initialization of the driver is compiled into the kernel and tries to
 initialize before filesystem with configuration file is mounted (and
 firmware is not built into the kernel). We can either try switch to
 request_firmware_nowait() or at least document that we need firmware at
 boot.
 

The reason I did not use request_firmware_nowait() is that this configuration 
data
includes information needed by probe (x/y resolution, interrupt trigger type, 
max
touch num), used in goodix_read_config, goodix_ts_report_touch  and for irq 
flags
when requesting the interrupt. I will document that we need this configuration
firmware at boot in the commit message and add a comment in the code.
Is there any other documentation I need to update?

 
  Signed-off-by: Octavian Purdila octavian.purd...@intel.com
  Signed-off-by: Irina Tirdea irina.tir...@intel.com
  ---
   drivers/input/touchscreen/goodix.c | 128 
  +
   1 file changed, 128 insertions(+)
 
  diff --git a/drivers/input/touchscreen/goodix.c 
  b/drivers/input/touchscreen/goodix.c
  index c345eb7..1ce9278 100644
  --- a/drivers/input/touchscreen/goodix.c
  +++ b/drivers/input/touchscreen/goodix.c
  @@ -24,6 +24,7 @@
   #include linux/interrupt.h
   #include linux/slab.h
   #include linux/acpi.h
  +#include linux/firmware.h
   #include linux/gpio.h
   #include linux/of.h
   #include asm/unaligned.h
  @@ -95,6 +96,39 @@ static int goodix_i2c_read(struct i2c_client *client,
  return ret  0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
   }
 
  +/**
  + * goodix_i2c_write - write data to a register of the i2c slave device.
  + *
  + * @client: i2c device.
  + * @reg: the register to write to.
  + * @buf: raw data buffer to write.
  + * @len: length of the buffer to write
  + */
  +static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 
  *buf,
  +   unsigned len)
  +{
  +   u8 *addr_buf;
  +   struct i2c_msg msg;
  +   int ret;
  +
  +   addr_buf = kmalloc(len + 2, GFP_KERNEL);
  +   if (!addr_buf)
  +   return -ENOMEM;
  +
  +   addr_buf[0] = reg  8;
  +   addr_buf[1] = reg  0xFF;
  +   memcpy(addr_buf[2], buf, len);
  +
  +   msg.flags = 0;
  +   msg.addr = client-addr;
  +   msg.buf = addr_buf;
  +   msg.len = len + 2;
  +
  +   ret = i2c_transfer(client-adapter, msg, 1);
  +   kfree(addr_buf);
  +   return ret  0 ? ret : (ret != 1 ? -EIO : 0);
  +}
  +
   static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
   {
  int touch_num;
  @@ -192,6 +226,95 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void 
  *dev_id)
  return IRQ_HANDLED;
   }
 
  +/**
  + * goodix_check_cfg - Checks if config buffer is valid
  + *
  + * @ts: goodix_ts_data pointer
  + * @fw: firmware config data
  + */
  +static int goodix_check_cfg(struct goodix_ts_data *ts,
  +   const struct firmware *fw)
  +{
  +   int i, raw_cfg_len;
  +   u8 check_sum = 0;
  +
  +   if (fw-size  GOODIX_CONFIG_MAX_LENGTH) {
  +   dev_err(ts-client-dev,
  +   The length of the config buffer array is not correct);
  +   return -EINVAL;
  +   }
  +
  +   raw_cfg_len = fw-size - 2;
  +   for (i = 0; i  raw_cfg_len; i++)
  +   check_sum += fw-data[i];
  +   check_sum = (~check_sum) + 1;
  +   if (check_sum != fw-data[raw_cfg_len]) {
  +   dev_err(ts-client-dev,
  +   The checksum of the config buffer array is not 
  correct);
  +   return -EINVAL;
  +   }
  +
  +   if (fw-data[raw_cfg_len + 1] != 1) {
  +   

RE: [PATCH v2 6/8] input: goodix: add power management support

2015-06-23 Thread Tirdea, Irina


 -Original Message-
 From: Dmitry Torokhov [mailto:dmitry.torok...@gmail.com]
 Sent: 09 June, 2015 21:16
 To: Tirdea, Irina
 Cc: Bastien Nocera; Mark Rutland; linux-input@vger.kernel.org; 
 devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Rob
 Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
 Subject: Re: [PATCH v2 6/8] input: goodix: add power management support
 
 On Mon, Jun 08, 2015 at 05:37:51PM +0300, Irina Tirdea wrote:
  Implement suspend/resume for goodix driver.
 
  This is based on Goodix datasheets for GT911 and GT9271
  and on Goodix driver gt9xx.c for Android (publicly available
  in Android kernel trees for various devices).
 
  Signed-off-by: Octavian Purdila octavian.purd...@intel.com
  Signed-off-by: Irina Tirdea irina.tir...@intel.com
  ---
   drivers/input/touchscreen/goodix.c | 88 
  +++---
   1 file changed, 83 insertions(+), 5 deletions(-)
 
  diff --git a/drivers/input/touchscreen/goodix.c 
  b/drivers/input/touchscreen/goodix.c
  index 1ce9278..903c83d 100644
  --- a/drivers/input/touchscreen/goodix.c
  +++ b/drivers/input/touchscreen/goodix.c
  @@ -38,6 +38,7 @@ struct goodix_ts_data {
  unsigned int int_trigger_type;
  struct gpio_desc *gpiod_int;
  struct gpio_desc *gpiod_rst;
  +   unsigned long irq_flags;
   };
 
   #define GOODIX_GPIO_INT_NAME   irq
  @@ -52,6 +53,9 @@ struct goodix_ts_data {
   #define GOODIX_CONFIG_MAX_LENGTH   240
 
   /* Register defines */
  +#define GOODIX_REG_COMMAND 0x8040
  +#define GOODIX_CMD_SCREEN_OFF  0x05
  +
   #define GOODIX_READ_COOR_ADDR  0x814E
   #define GOODIX_REG_CONFIG_DATA 0x8047
   #define GOODIX_REG_ID  0x8140
  @@ -129,6 +133,11 @@ static int goodix_i2c_write(struct i2c_client *client, 
  u16 reg, const u8 *buf,
  return ret  0 ? ret : (ret != 1 ? -EIO : 0);
   }
 
  +static int goodix_i2c_write_u8(struct i2c_client *client, u16 reg, u8 
  value)
  +{
  +   return goodix_i2c_write(client, reg, value, sizeof(value));
  +}
  +
   static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 *data)
   {
  int touch_num;
  @@ -226,6 +235,18 @@ static irqreturn_t goodix_ts_irq_handler(int irq, void 
  *dev_id)
  return IRQ_HANDLED;
   }
 
  +static void goodix_free_irq(struct goodix_ts_data *ts)
  +{
  +   devm_free_irq(ts-client-dev, ts-client-irq, ts);
  +}
  +
  +static int goodix_request_irq(struct goodix_ts_data *ts)
  +{
  +   return devm_request_threaded_irq(ts-client-dev, ts-client-irq,
  +NULL, goodix_ts_irq_handler,
  +ts-irq_flags, ts-client-name, ts);
  +}
  +
   /**
* goodix_check_cfg - Checks if config buffer is valid
*
  @@ -547,7 +568,6 @@ static int goodix_ts_probe(struct i2c_client *client,
 const struct i2c_device_id *id)
   {
  struct goodix_ts_data *ts;
  -   unsigned long irq_flags;
  int error;
  u16 version_info, id_info;
 
  @@ -599,10 +619,8 @@ static int goodix_ts_probe(struct i2c_client *client,
  if (error)
  return error;
 
  -   irq_flags = goodix_irq_flags[ts-int_trigger_type] | IRQF_ONESHOT;
  -   error = devm_request_threaded_irq(ts-client-dev, client-irq,
  - NULL, goodix_ts_irq_handler,
  - irq_flags, client-name, ts);
  +   ts-irq_flags = goodix_irq_flags[ts-int_trigger_type] | IRQF_ONESHOT;
  +   error = goodix_request_irq(ts);
  if (error) {
  dev_err(client-dev, request IRQ failed: %d\n, error);
  return error;
  @@ -611,6 +629,65 @@ static int goodix_ts_probe(struct i2c_client *client,
  return 0;
   }
 
  +#ifdef CONFIG_PM_SLEEP
  +static int goodix_suspend(struct device *dev)
 
 Please drop #ifdef CONFIG_PM_SLEEP and annotate with __maybe_unused
 instead.
 
Ok, will fix this.

  +{
  +   struct i2c_client *client = to_i2c_client(dev);
  +   struct goodix_ts_data *ts = i2c_get_clientdata(client);
  +   int ret;
  +
  +   goodix_free_irq(ts);
 
 Why do we need to free IRQ here?
 

The suspend sequence described in Goodix datasheets requires using the irq pin 
as output pin.
If the interrupt is not released, gpiod_direction_output(ts-gpiod_int, 0) will 
fail with the message
tried to set a GPIO tied to an IRQ as output.  Initially I used 
gpiod_lock/unlock_as_irq, but this API
is no longer available (and gpiochip_lock_as_irq is only available for gpio 
chips). Is there a better way
to do this?

  +   /* Output LOW on the INT pin for 5 ms */
  +   ret = gpiod_direction_output(ts-gpiod_int, 0);
  +   if (ret) {
  +   goodix_request_irq(ts);
  +   return ret;
  +   }
  +   usleep_range(5000, 6000);
  +
  +   ret = goodix_i2c_write_u8(ts-client, GOODIX_REG_COMMAND,
  + GOODIX_CMD_SCREEN_OFF);
  +   if (ret) {
  +   dev_err(ts-client-dev, Screen off 

Re: [PATCH v5 1/2] dt: add cap11xx LED documentation

2015-06-23 Thread Matt Ranostay
On Tue, Jun 23, 2015 at 1:36 AM, Jacek Anaszewski
j.anaszew...@samsung.com wrote:
 On 06/22/2015 07:59 PM, Dmitry Torokhov wrote:

 On Wed, Jun 17, 2015 at 08:58:16PM -0700, Matt Ranostay wrote:

 Signed-off-by: Matt Ranostay mranos...@gmail.com
 ---
   .../devicetree/bindings/input/cap11xx.txt  | 25
 ++
   1 file changed, 25 insertions(+)

 diff --git a/Documentation/devicetree/bindings/input/cap11xx.txt
 b/Documentation/devicetree/bindings/input/cap11xx.txt
 index 7d0a300..09cdc43 100644
 --- a/Documentation/devicetree/bindings/input/cap11xx.txt
 +++ b/Documentation/devicetree/bindings/input/cap11xx.txt
 @@ -38,6 +38,11 @@ Optional properties:
 defaults. The array must have exactly six
 entries.

 +   linux,led-brightness:   Defines the ON brightness when the
 optional LED
 +   functionality is used. Valid values are
 1-15.
 +   By default a value of 15 is set.


 Please mention the device does not allow controlling brightness of leds
 individually and that is why this property is at device level, not
 individual led level.


 I've just noticed that we have drivers/leds/leds-netxbig.c driver, which
 also doesn't allow controlling the LEDs on extension board individually,
 but it still does allow changing their brightness. I am leaning towards
 allowing this also for this driver and adding similar comment in the
 source code like at the line 218 of the aforementioned driver.
 As a result this property wouldn't be required.


Ok that should be pretty simple to do. But seems kind weird to have
each led channel to be changing the brightness of all.  Wouldn't the
brightness sysfs entries of the other led channels be showing
incorrect values?

 Also, why does it have linux prefix? It does not appear to control
 any linux-specific functionality.



 --
 Best Regards,
 Jacek Anaszewski
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 1/2] dt: add cap11xx LED documentation

2015-06-23 Thread Matt Ranostay
On Tue, Jun 23, 2015 at 11:07 AM, Dmitry Torokhov
dmitry.torok...@gmail.com wrote:
 On Tue, Jun 23, 2015 at 10:23:57AM -0700, Matt Ranostay wrote:
 On Tue, Jun 23, 2015 at 1:36 AM, Jacek Anaszewski
 j.anaszew...@samsung.com wrote:
  On 06/22/2015 07:59 PM, Dmitry Torokhov wrote:
 
  On Wed, Jun 17, 2015 at 08:58:16PM -0700, Matt Ranostay wrote:
 
  Signed-off-by: Matt Ranostay mranos...@gmail.com
  ---
.../devicetree/bindings/input/cap11xx.txt  | 25
  ++
1 file changed, 25 insertions(+)
 
  diff --git a/Documentation/devicetree/bindings/input/cap11xx.txt
  b/Documentation/devicetree/bindings/input/cap11xx.txt
  index 7d0a300..09cdc43 100644
  --- a/Documentation/devicetree/bindings/input/cap11xx.txt
  +++ b/Documentation/devicetree/bindings/input/cap11xx.txt
  @@ -38,6 +38,11 @@ Optional properties:
  defaults. The array must have exactly six
  entries.
 
  +   linux,led-brightness:   Defines the ON brightness when the
  optional LED
  +   functionality is used. Valid values are
  1-15.
  +   By default a value of 15 is set.
 
 
  Please mention the device does not allow controlling brightness of leds
  individually and that is why this property is at device level, not
  individual led level.
 
 
  I've just noticed that we have drivers/leds/leds-netxbig.c driver, which
  also doesn't allow controlling the LEDs on extension board individually,
  but it still does allow changing their brightness. I am leaning towards
  allowing this also for this driver and adding similar comment in the
  source code like at the line 218 of the aforementioned driver.
  As a result this property wouldn't be required.
 

 Ok that should be pretty simple to do. But seems kind weird to have
 each led channel to be changing the brightness of all.  Wouldn't the
 brightness sysfs entries of the other led channels be showing
 incorrect values?

 I agree, this is kind of weird. Maybe we should have a device-specific
 attribute (on the platform device level) that allows controlling overall
 brightness, but I think LEDs should be just on/off with max brightness
 of 1. Userspace should not have to be aware about the fact that on that
 particular device LEDs are not completely independent as far as their
 brightness goes.

So should I drop the devicetree part of the patch in v6?


 Thanks.

 --
 Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] touchscreen: sun4i-ts: Really fix A10 temperature reporting

2015-06-23 Thread Dmitry Torokhov
On Tue, Jun 23, 2015 at 09:46:20PM +0200, Hans de Goede wrote:
 Hi,
 
 On 06/23/2015 05:06 PM, m.silentcr...@gmail.com wrote:
 Hi Hans,
 
 is it possible that this patch (and the parent commit Input: sun4i-ts - 
 allow controlling filter and sensitivity via DT) has quite an adversial 
 effect on other boards than the ones tested?
 
 On my Lemaker Bananapi the temperature is now being reported as somwhere 
 between -15°C to -10°C with the latest Kernel 4.1.0. These negative values 
 are obviously way off. On Kernel 4.0.5 the temperature reading was usually 
 around 40°C. While that might not have been accurate either, it was at least 
 plausible.
 
 The temperature curve for the A20 SoC was not changed, if it did change then
 you're using an old dtb file with a new kernel, you must always update your
 dtb file together with the kernel.

Umm, we should keep compatibility with old DTS...

 
 
 
 
 Given that there is no Documentation and things seem quite board-specific, I 
 really don't know how this could be improved, so I can merely report my 
 observation.
 
 Kind regards,
 
 Timo
 
 
 Am Montag, 9. März 2015 10:38:02 UTC+1 schrieb Hans de Goede:
 The commit titled:
 touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
 contains a math error, the offset it uses is in degrees, but the actual code
 applies the offset before multiplying by stepsize :|
 
 Given that this is rather backwards (every math course ever thought applies
 the multiplication before the offset for linear functions), this commit
 fixes things by changing the code applying the offset to do the logical
 thing, adjusting the offset for the other models accordingly.
 
 This has been tested on an A10, A13, A20 and A31 to make sure everything 
 really
 is correct now.
 
 Signed-off-by: Hans de Goede hdego...@redhat.com
 ---
 Note if possible this commit should be squashed into the original
 touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
 commit as a fixup.
 ---
   drivers/input/touchscreen/sun4i-ts.c | 14 +++---
   1 file changed, 7 insertions(+), 7 deletions(-)
 
 diff --git a/drivers/input/touchscreen/sun4i-ts.c 
 b/drivers/input/touchscreen/sun4i-ts.c
 index 66ccd5a..178d2ef 100644
 --- a/drivers/input/touchscreen/sun4i-ts.c
 +++ b/drivers/input/touchscreen/sun4i-ts.c
 @@ -193,7 +193,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data 
 *ts, long *temp)
 if (ts-temp_data == -1)
 return -EAGAIN;
 
 -   *temp = (ts-temp_data - ts-temp_offset) * ts-temp_step;
 +   *temp = ts-temp_data * ts-temp_step - ts-temp_offset;
 
 return 0;
   }
 @@ -255,17 +255,17 @@ static int sun4i_ts_probe(struct platform_device 
 *pdev)
 ts-ignore_fifo_data = true;
 ts-temp_data = -1;
 if (of_device_is_compatible(np, allwinner,sun6i-a31-ts)) {
 -   /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
 -   ts-temp_offset = 1626;
 +   /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
 +   ts-temp_offset = 271000;
 ts-temp_step = 167;
 } else if (of_device_is_compatible(np, allwinner,sun4i-a10-ts)) {
 /*
  * The A10 temperature sensor has quite a wide spread, these
  * parameters are based on the averaging of the calibration
  * results of 4 completely different boards, with a spread of
 -* temp_step from 96 - 170 and temp_offset from 1758 - 3310.
 +* temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
  */
 -   ts-temp_offset = 2570;
 +   ts-temp_offset = 257000;
 ts-temp_step = 133;
 } else {
 /*
 @@ -273,13 +273,13 @@ static int sun4i_ts_probe(struct platform_device 
 *pdev)
  * the temperature. The formula used here is from the AXP209,
  * which is designed by X-Powers, an affiliate of Allwinner:
  *
 -* temperature = -144.7 + (value * 0.1)
 +* temperature (C) = (value * 0.1) - 144.7
  *
  * Allwinner does not have any documentation whatsoever for
  * this hardware. Moreover, it is claimed that the sensor
  * is inaccurate and cannot work properly.
  */
 -   ts-temp_offset = 1447;
 +   ts-temp_offset = 144700;
 ts-temp_step = 100;
 }
 
 --
 2.3.1
 
 
 Regards,
 
 Hans

-- 
Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 5/8] input: goodix: write configuration data to device

2015-06-23 Thread Dmitry Torokhov
On Tue, Jun 23, 2015 at 01:27:01PM +, Tirdea, Irina wrote:
 
 
  -Original Message-
  From: linux-input-ow...@vger.kernel.org 
  [mailto:linux-input-ow...@vger.kernel.org] On Behalf Of Dmitry Torokhov
  Sent: 09 June, 2015 21:14
  To: Tirdea, Irina
  Cc: Bastien Nocera; Mark Rutland; linux-input@vger.kernel.org; 
  devicet...@vger.kernel.org; linux-ker...@vger.kernel.org; Rob
  Herring; Pawel Moll; Ian Campbell; Kumar Gala; Purdila, Octavian
  Subject: Re: [PATCH v2 5/8] input: goodix: write configuration data to 
  device
  
  Hi Irina,
  
 
 Hi Dmitry,
 
  On Mon, Jun 08, 2015 at 05:37:50PM +0300, Irina Tirdea wrote:
   Goodix devices can be configured by writing custom data to the device at
   init. The configuration data is read with request_firmware from
   goodix_id_cfg.bin, where id is the product id read from the device
   (e.g.: goodix_911_cfg.bin for Goodix GT911, goodix_9271_cfg.bin for
   GT9271).
  
   The configuration information has a specific format described in the 
   Goodix
   datasheet. It includes X/Y resolution, maximum supported touch points,
   interrupt flags, various sesitivity factors and settings for advanced
   features (like gesture recognition).
  
   This is based on Goodix datasheets for GT911 and GT9271 and on Goodix
   driver gt9xx.c for Android (publicly available in Android kernel
   trees for various devices).
  
  I am afraid that just using request_firmware() in probe() is not the
  best option as it may cause either errors or delays in
  initialization of the driver is compiled into the kernel and tries to
  initialize before filesystem with configuration file is mounted (and
  firmware is not built into the kernel). We can either try switch to
  request_firmware_nowait() or at least document that we need firmware at
  boot.
  
 
 The reason I did not use request_firmware_nowait() is that this configuration 
 data
 includes information needed by probe (x/y resolution, interrupt trigger type, 
 max
 touch num), used in goodix_read_config, goodix_ts_report_touch  and for irq 
 flags
 when requesting the interrupt. I will document that we need this configuration
 firmware at boot in the commit message and add a comment in the code.
 Is there any other documentation I need to update?
 
  
   Signed-off-by: Octavian Purdila octavian.purd...@intel.com
   Signed-off-by: Irina Tirdea irina.tir...@intel.com
   ---
drivers/input/touchscreen/goodix.c | 128 
   +
1 file changed, 128 insertions(+)
  
   diff --git a/drivers/input/touchscreen/goodix.c 
   b/drivers/input/touchscreen/goodix.c
   index c345eb7..1ce9278 100644
   --- a/drivers/input/touchscreen/goodix.c
   +++ b/drivers/input/touchscreen/goodix.c
   @@ -24,6 +24,7 @@
#include linux/interrupt.h
#include linux/slab.h
#include linux/acpi.h
   +#include linux/firmware.h
#include linux/gpio.h
#include linux/of.h
#include asm/unaligned.h
   @@ -95,6 +96,39 @@ static int goodix_i2c_read(struct i2c_client *client,
 return ret  0 ? ret : (ret != ARRAY_SIZE(msgs) ? -EIO : 0);
}
  
   +/**
   + * goodix_i2c_write - write data to a register of the i2c slave device.
   + *
   + * @client: i2c device.
   + * @reg: the register to write to.
   + * @buf: raw data buffer to write.
   + * @len: length of the buffer to write
   + */
   +static int goodix_i2c_write(struct i2c_client *client, u16 reg, const u8 
   *buf,
   + unsigned len)
   +{
   + u8 *addr_buf;
   + struct i2c_msg msg;
   + int ret;
   +
   + addr_buf = kmalloc(len + 2, GFP_KERNEL);
   + if (!addr_buf)
   + return -ENOMEM;
   +
   + addr_buf[0] = reg  8;
   + addr_buf[1] = reg  0xFF;
   + memcpy(addr_buf[2], buf, len);
   +
   + msg.flags = 0;
   + msg.addr = client-addr;
   + msg.buf = addr_buf;
   + msg.len = len + 2;
   +
   + ret = i2c_transfer(client-adapter, msg, 1);
   + kfree(addr_buf);
   + return ret  0 ? ret : (ret != 1 ? -EIO : 0);
   +}
   +
static int goodix_ts_read_input_report(struct goodix_ts_data *ts, u8 
   *data)
{
 int touch_num;
   @@ -192,6 +226,95 @@ static irqreturn_t goodix_ts_irq_handler(int irq, 
   void *dev_id)
 return IRQ_HANDLED;
}
  
   +/**
   + * goodix_check_cfg - Checks if config buffer is valid
   + *
   + * @ts: goodix_ts_data pointer
   + * @fw: firmware config data
   + */
   +static int goodix_check_cfg(struct goodix_ts_data *ts,
   + const struct firmware *fw)
   +{
   + int i, raw_cfg_len;
   + u8 check_sum = 0;
   +
   + if (fw-size  GOODIX_CONFIG_MAX_LENGTH) {
   + dev_err(ts-client-dev,
   + The length of the config buffer array is not correct);
   + return -EINVAL;
   + }
   +
   + raw_cfg_len = fw-size - 2;
   + for (i = 0; i  raw_cfg_len; i++)
   + check_sum += fw-data[i];
   + check_sum = (~check_sum) + 1;
   + if (check_sum != fw-data[raw_cfg_len]) {
   + dev_err(ts-client-dev,
   + The checksum of 

Re: [PATCH] Input :Optimize input_dev_release_keys function

2015-06-23 Thread Anshul Garg
Hello Mr. Dmitry,

Yes it was actually a typo.
I have tested the code with resetting key structure instead of keybit.

I have resent the patch for the review.

Please check.


On Wed, Jun 24, 2015 at 12:27 AM, Dmitry Torokhov
dmitry.torok...@gmail.com wrote:
 On Tue, Jun 23, 2015 at 11:08:23AM -0700, Anshul Garg wrote:
 From: Anshul Garg aksgarg1...@gmail.com

 input_dev_release_keys : Use for_each_set_bit instead
 of testing every bit upto KEY_MAX as it is more clean
 and more optimized.

 input_estimate_events_per_packet : Use bitmap_weight
 to get set bits count for EV_REL type instead of using
 loop and also use for_each_set_bit for EV_ABS event for
 more optimized code.

 Signed-off-by: Anshul Garg aksgarg1...@gmail.com
 ---
  drivers/input/input.c |   28 ++--
  1 file changed, 10 insertions(+), 18 deletions(-)

 diff --git a/drivers/input/input.c b/drivers/input/input.c
 index e0b7b8e..9459f8b 100644
 --- a/drivers/input/input.c
 +++ b/drivers/input/input.c
 @@ -682,12 +682,9 @@ static void input_dev_release_keys(struct input_dev 
 *dev)
   int code;

   if (is_event_supported(EV_KEY, dev-evbit, EV_MAX)) {
 - for (code = 0; code = KEY_MAX; code++) {
 - if (is_event_supported(code, dev-keybit, KEY_MAX) 
 - __test_and_clear_bit(code, dev-key)) {
 - input_pass_event(dev, EV_KEY, code, 0);
 - }
 - }
 + for_each_set_bit(code, dev-keybit, KEY_MAX)
 + input_pass_event(dev, EV_KEY, code, 0);
 + memset(dev-keybit, 0, sizeof(dev-keybit));

 I do not think this will work, you are resetting wrong bitmap.
 dev-keybit represents keys the device is capable of sending while
 dev-key represents keys that are currently pressed. Once your code is
 ran you should not get any more key events.

 How was this tested?

 Thanks.

 --
 Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 1/2] dt: add cap11xx LED documentation

2015-06-23 Thread Dmitry Torokhov
On Tue, Jun 23, 2015 at 10:23:57AM -0700, Matt Ranostay wrote:
 On Tue, Jun 23, 2015 at 1:36 AM, Jacek Anaszewski
 j.anaszew...@samsung.com wrote:
  On 06/22/2015 07:59 PM, Dmitry Torokhov wrote:
 
  On Wed, Jun 17, 2015 at 08:58:16PM -0700, Matt Ranostay wrote:
 
  Signed-off-by: Matt Ranostay mranos...@gmail.com
  ---
.../devicetree/bindings/input/cap11xx.txt  | 25
  ++
1 file changed, 25 insertions(+)
 
  diff --git a/Documentation/devicetree/bindings/input/cap11xx.txt
  b/Documentation/devicetree/bindings/input/cap11xx.txt
  index 7d0a300..09cdc43 100644
  --- a/Documentation/devicetree/bindings/input/cap11xx.txt
  +++ b/Documentation/devicetree/bindings/input/cap11xx.txt
  @@ -38,6 +38,11 @@ Optional properties:
  defaults. The array must have exactly six
  entries.
 
  +   linux,led-brightness:   Defines the ON brightness when the
  optional LED
  +   functionality is used. Valid values are
  1-15.
  +   By default a value of 15 is set.
 
 
  Please mention the device does not allow controlling brightness of leds
  individually and that is why this property is at device level, not
  individual led level.
 
 
  I've just noticed that we have drivers/leds/leds-netxbig.c driver, which
  also doesn't allow controlling the LEDs on extension board individually,
  but it still does allow changing their brightness. I am leaning towards
  allowing this also for this driver and adding similar comment in the
  source code like at the line 218 of the aforementioned driver.
  As a result this property wouldn't be required.
 
 
 Ok that should be pretty simple to do. But seems kind weird to have
 each led channel to be changing the brightness of all.  Wouldn't the
 brightness sysfs entries of the other led channels be showing
 incorrect values?

I agree, this is kind of weird. Maybe we should have a device-specific
attribute (on the platform device level) that allows controlling overall
brightness, but I think LEDs should be just on/off with max brightness
of 1. Userspace should not have to be aware about the fact that on that
particular device LEDs are not completely independent as far as their
brightness goes.

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Input :Optimize input_dev_release_keys function

2015-06-23 Thread Dmitry Torokhov
On Tue, Jun 23, 2015 at 11:08:23AM -0700, Anshul Garg wrote:
 From: Anshul Garg aksgarg1...@gmail.com
 
 input_dev_release_keys : Use for_each_set_bit instead
 of testing every bit upto KEY_MAX as it is more clean
 and more optimized.
 
 input_estimate_events_per_packet : Use bitmap_weight
 to get set bits count for EV_REL type instead of using
 loop and also use for_each_set_bit for EV_ABS event for
 more optimized code.
 
 Signed-off-by: Anshul Garg aksgarg1...@gmail.com
 ---
  drivers/input/input.c |   28 ++--
  1 file changed, 10 insertions(+), 18 deletions(-)
 
 diff --git a/drivers/input/input.c b/drivers/input/input.c
 index e0b7b8e..9459f8b 100644
 --- a/drivers/input/input.c
 +++ b/drivers/input/input.c
 @@ -682,12 +682,9 @@ static void input_dev_release_keys(struct input_dev *dev)
   int code;
  
   if (is_event_supported(EV_KEY, dev-evbit, EV_MAX)) {
 - for (code = 0; code = KEY_MAX; code++) {
 - if (is_event_supported(code, dev-keybit, KEY_MAX) 
 - __test_and_clear_bit(code, dev-key)) {
 - input_pass_event(dev, EV_KEY, code, 0);
 - }
 - }
 + for_each_set_bit(code, dev-keybit, KEY_MAX)
 + input_pass_event(dev, EV_KEY, code, 0);
 + memset(dev-keybit, 0, sizeof(dev-keybit));

I do not think this will work, you are resetting wrong bitmap.
dev-keybit represents keys the device is capable of sending while
dev-key represents keys that are currently pressed. Once your code is
ran you should not get any more key events.

How was this tested?

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 06/11] Input: synaptics-rmi4 - add a reset callback

2015-06-23 Thread Benjamin Tissoires
When a device is physically reset, the transport layer may need to reset
its state too and also do extra work to make the device accessible on the
bus.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_bus.h| 1 +
 drivers/input/rmi4/rmi_driver.c | 8 
 2 files changed, 9 insertions(+)

diff --git a/drivers/input/rmi4/rmi_bus.h b/drivers/input/rmi4/rmi_bus.h
index d4cfc85..41d6c3d 100644
--- a/drivers/input/rmi4/rmi_bus.h
+++ b/drivers/input/rmi4/rmi_bus.h
@@ -197,6 +197,7 @@ struct rmi_transport_ops {
 
int (*enable_device) (struct rmi_transport_dev *xport);
void (*disable_device) (struct rmi_transport_dev *xport);
+   int (*reset)(struct rmi_transport_dev *xport, u16 reset_addr);
 };
 
 /**
diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 264bc62..81e7c55 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -611,6 +611,14 @@ static int rmi_initial_reset(struct rmi_device *rmi_dev,
const struct rmi_device_platform_data *pdata =
rmi_get_platform_data(rmi_dev);
 
+   if (rmi_dev-xport-ops-reset) {
+   if (rmi_dev-xport-ops-reset(rmi_dev-xport,
+  cmd_addr))
+   return error;
+
+   return RMI_SCAN_DONE;
+   }
+
error = rmi_write_block(rmi_dev, cmd_addr, cmd_buf, 1);
if (error) {
dev_err(rmi_dev-dev,
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 00/11] Input: synaptics-rmi4: various fixes for the existing rmi4 branch

2015-06-23 Thread Benjamin Tissoires
Hi Dmitry,

As mentioned in the thread on linux-i2c[1], I am making good progress on the
RMI4 SMBus implementation [2].
I am still missing the PS/2 pass-through function but I have an intern 
(Chandler,
CC-ed) working on that. Also, I believe forcepads could used RMI4 but we will
have to implement the ForcePad feature first :)

Instead of waiting for both the i2c SMBus feature to be validated and the driver
to be feature equivalent (greater actually because it tracks 5 fingers instead
of 1 and a half), I am sending those first fixes to you for the branch
synaptics-rmi4.

Andrew, Christopher, I am not 100% sure regarding the Signed-off and acked-by
for the implementation of function 30 and the SMBus transport layer in my tree
(I smashed a bunch of commits so the result differs from what you saw last 
time).
Could you validate this?

Cheers,
Benjamin


[1] http://www.spinics.net/lists/linux-i2c/msg20241.html
[2] https://github.com/bentiss/linux branch synaptics-rmi4-smbus-v4.1-15-06-23

Benjamin Tissoires (11):
  Input: synaptics-rmi4 - embed the function modules in rmi_core
  Input: synaptics-rmi4 - add a common input device in rmi_driver
  Input: synaptics-rmi4 - explicitly request polling when needed
  Input: synaptics-rmi4 - prevent oopses when irq arrives while the
device is not bound
  Input: synaptics-rmi4 - call rmi_driver_process_config_requests in
enable_sensor
  Input: synaptics-rmi4 - add a reset callback
  Input: synaptics-rmi4 - f11: fix bitmap irq check
  Input: synaptics-rmi4 - f11: use the unified input node if available
  Input: synaptics-rmi4 - f11: clean up rmi_f11_finger_handler
  Input: synaptics-rmi4 - f11: allow the top software button property to
be set
  Input: synaptics-rmi4 - f11: add support for kernel tracking

 drivers/input/rmi4/Kconfig  |   5 +-
 drivers/input/rmi4/Makefile |   2 +-
 drivers/input/rmi4/rmi_bus.c|  11 +-
 drivers/input/rmi4/rmi_bus.h|   1 +
 drivers/input/rmi4/rmi_driver.c | 146 +++---
 drivers/input/rmi4/rmi_driver.h |  17 +++
 drivers/input/rmi4/rmi_f01.c|   7 ++
 drivers/input/rmi4/rmi_f11.c| 262 ++--
 include/linux/rmi.h |  22 +++-
 9 files changed, 326 insertions(+), 147 deletions(-)

-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 04/11] Input: synaptics-rmi4 - prevent oopses when irq arrives while the device is not bound

2015-06-23 Thread Benjamin Tissoires
If the device has been registered but is not populated, we should not
process any incoming interrupt.
Make sure the pointers we are following are valid.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_driver.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 2fdc7e8..fe5f2f9 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -279,6 +279,9 @@ int rmi_process_interrupt_requests(struct rmi_device 
*rmi_dev)
struct rmi_function *entry;
int error;
 
+   if (!data || !data-f01_container || !data-irq_status)
+   return 0;
+
error = rmi_read_block(rmi_dev,
data-f01_container-fd.data_base_addr + 1,
data-irq_status, data-num_of_irq_regs);
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 11/11] Input: synaptics-rmi4 - f11: add support for kernel tracking

2015-06-23 Thread Benjamin Tissoires
Kernel tracking is used in 2 use cases:
- filter out jumps when the sensor is not relieable enough
- provide a MT protocol B when the sensor is providing MT protocol A data

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_f11.c | 152 +--
 include/linux/rmi.h  |  14 ++--
 2 files changed, 114 insertions(+), 52 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 50df7a1..8bccc8a 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -65,6 +65,9 @@
  * devices currently in the field.
  */
 
+/* maximum ABS_MT_POSITION displacement (in mm) */
+#define DMAX 10
+
 /**
  * @rezero - writing this to the F11 command register will cause the sensor to
  * calibrate to the current capacitive state.
@@ -497,9 +500,6 @@ struct f11_2d_data {
  * @data_pkt - buffer for data reported by this sensor.
  * @pkt_size - number of bytes in that buffer.
  * @sensor_index - identifies this particular 2D touch sensor
- * @type_a - some early RMI4 2D sensors do not reliably track the finger
- * position when two fingers are on the device.  When this is true, we
- * assume we have one of those sensors and report events appropriately.
  * @sensor_type - indicates whether we're touchscreen or touchpad.
  * @input - input device for absolute pointing stream
  * @input_phys - buffer for the absolute phys name for this sensor.
@@ -508,13 +508,16 @@ struct f11_2d_sensor {
struct rmi_f11_2d_axis_alignment axis_align;
struct f11_2d_sensor_queries sens_query;
struct f11_2d_data data;
+   struct input_mt_pos *tracking_pos;
+   int *tracking_slots;
+   bool kernel_tracking;
+   int dmax;
u16 max_x;
u16 max_y;
u8 nbr_fingers;
u8 *data_pkt;
int pkt_size;
u8 sensor_index;
-   u32 type_a; /* boolean but debugfs API requires u32 */
bool topbuttonpad;
enum rmi_f11_sensor_type sensor_type;
struct input_dev *input;
@@ -604,6 +607,53 @@ static void rmi_f11_rel_pos_report(struct f11_2d_sensor 
*sensor, u8 n_finger)
}
 }
 
+static void rmi_f11_abs_parse_xy(struct f11_data *f11,
+struct f11_2d_sensor *sensor,
+enum f11_finger_state finger_state,
+u8 n_finger)
+{
+   struct f11_2d_data *data = sensor-data;
+   struct rmi_f11_2d_axis_alignment *axis_align = sensor-axis_align;
+   u8 *pos_data = data-abs_pos[n_finger * RMI_F11_ABS_BYTES];
+   u16 x, y;
+
+   /* we keep the previous values if the finger is released */
+   if (!finger_state)
+   return;
+
+   x = (pos_data[0]  4) | (pos_data[2]  0x0F);
+   y = (pos_data[1]  4) | (pos_data[2]  4);
+
+   if (axis_align-swap_axes)
+   swap(x, y);
+
+   if (axis_align-flip_x)
+   x = max(sensor-max_x - x, 0);
+
+   if (axis_align-flip_y)
+   y = max(sensor-max_y - y, 0);
+
+   /*
+* Here checking if X offset or y offset are specified is
+* redundant. We just add the offsets or clip the values.
+*
+* Note: offsets need to be applied before clipping occurs,
+* or we could get funny values that are outside of
+* clipping boundaries.
+*/
+   x += axis_align-offset_x;
+   y += axis_align-offset_y;
+   x =  max(axis_align-clip_x_low, x);
+   y =  max(axis_align-clip_y_low, y);
+   if (axis_align-clip_x_high)
+   x = min(axis_align-clip_x_high, x);
+   if (axis_align-clip_y_high)
+   y =  min(axis_align-clip_y_high, y);
+
+   sensor-tracking_pos[n_finger].x = x;
+   sensor-tracking_pos[n_finger].y = y;
+}
+
 static void rmi_f11_abs_pos_report(struct f11_data *f11,
   struct f11_2d_sensor *sensor,
   enum f11_finger_state finger_state,
@@ -617,44 +667,16 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
int w_x, w_y, w_max, w_min, orient;
int tool_type = rmi_f11_get_tool_type(sensor, finger_state);
 
-   if (sensor-type_a) {
-   input_report_abs(input, ABS_MT_TRACKING_ID, n_finger);
-   input_report_abs(input, ABS_MT_TOOL_TYPE, tool_type);
-   } else {
+   if (sensor-kernel_tracking)
+   input_mt_slot(input, sensor-tracking_slots[n_finger]);
+   else
input_mt_slot(input, n_finger);
-   input_mt_report_slot_state(input, tool_type,
-  finger_state != F11_NO_FINGER);
-   }
+   input_mt_report_slot_state(input, tool_type,
+  finger_state != F11_NO_FINGER);
 
if (finger_state) {
-   x = (pos_data[0]  4) | (pos_data[2]  0x0F);
-   y = (pos_data[1]  4) | (pos_data[2]  4);
-

[PATCH 03/11] Input: synaptics-rmi4 - explicitly request polling when needed

2015-06-23 Thread Benjamin Tissoires
Host Notify does not work with neither IRQ nor polling. Allow a RMI4 driver
to request or not polling depending on the attn_gpio.

When neither the internal IRQ or polling systems are used, the
transport driver can call rmi_process_interrupt_requests() to
trigger a process of the alert.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_driver.c | 18 +-
 drivers/input/rmi4/rmi_driver.h |  3 +++
 include/linux/rmi.h |  3 +++
 3 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index 95f9386..2fdc7e8 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -67,15 +67,13 @@ static irqreturn_t rmi_irq_thread(int irq, void *p)
return IRQ_HANDLED;
 }
 
-static int process_interrupt_requests(struct rmi_device *rmi_dev);
-
 static void rmi_poll_work(struct work_struct *work)
 {
struct rmi_driver_data *data =
container_of(work, struct rmi_driver_data, poll_work);
struct rmi_device *rmi_dev = data-rmi_dev;
 
-   process_interrupt_requests(rmi_dev);
+   rmi_process_interrupt_requests(rmi_dev);
 }
 
 /*
@@ -124,7 +122,7 @@ static void disable_sensor(struct rmi_device *rmi_dev)
if (!data-enabled)
return;
 
-   if (!data-irq)
+   if (data-polling)
disable_polling(rmi_dev);
 
if (rmi_dev-xport-ops-disable_device)
@@ -163,7 +161,7 @@ static int enable_sensor(struct rmi_device *rmi_dev)
dev_name(rmi_dev-dev), xport);
if (retval)
return retval;
-   } else {
+   } else if (data-polling) {
retval = enable_polling(rmi_dev);
if (retval  0)
return retval;
@@ -171,7 +169,7 @@ static int enable_sensor(struct rmi_device *rmi_dev)
 
data-enabled = true;
 
-   return process_interrupt_requests(rmi_dev);
+   return rmi_process_interrupt_requests(rmi_dev);
 }
 
 static void rmi_free_function_list(struct rmi_device *rmi_dev)
@@ -274,7 +272,7 @@ static void process_one_interrupt(struct rmi_driver_data 
*data,
}
 }
 
-static int process_interrupt_requests(struct rmi_device *rmi_dev)
+int rmi_process_interrupt_requests(struct rmi_device *rmi_dev)
 {
struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);
struct device *dev = rmi_dev-dev;
@@ -315,6 +313,7 @@ static int process_interrupt_requests(struct rmi_device 
*rmi_dev)
 
return 0;
 }
+EXPORT_SYMBOL_GPL(rmi_process_interrupt_requests);
 
 /**
  * rmi_driver_set_input_params - set input device id and other data.
@@ -421,7 +420,7 @@ static int rmi_driver_irq_handler(struct rmi_device 
*rmi_dev, int irq)
return 0;
}
 
-   return process_interrupt_requests(rmi_dev);
+   return rmi_process_interrupt_requests(rmi_dev);
 }
 
 static int rmi_driver_reset_handler(struct rmi_device *rmi_dev)
@@ -949,10 +948,11 @@ static int rmi_driver_probe(struct device *dev)
}
}
}
-   } else {
+   } else if (pdata-attn_gpio == RMI_POLLING) {
data-poll_interval = ktime_set(0,
(pdata-poll_interval_ms ? pdata-poll_interval_ms :
DEFAULT_POLL_INTERVAL_MS) * 1000 * 1000);
+   data-polling = true;
}
 
if (data-f01_container-dev.driver) {
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 36ca34b..8a2d91a 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -43,6 +43,7 @@ struct rmi_driver_data {
u32 attn_count;
u32 irq_debug;  /* Should be bool, but debugfs wants u32 */
bool gpio_held;
+   bool polling;
int irq;
int irq_flags;
int num_of_irq_regs;
@@ -115,6 +116,8 @@ bool rmi_is_physical_driver(struct device_driver *);
 int rmi_register_physical_driver(void);
 void rmi_unregister_physical_driver(void);
 
+int rmi_process_interrupt_requests(struct rmi_device *rmi_dev);
+
 int rmi_register_f01_handler(void);
 void rmi_unregister_f01_handler(void);
 char *rmi_f01_get_product_ID(struct rmi_function *fn);
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index 1d22985..b771f41 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -23,6 +23,9 @@
 #include linux/wait.h
 #include linux/debugfs.h
 
+#define RMI_POLLING-1
+#define RMI_CUSTOM_IRQ -2
+
 enum rmi_attn_polarity {
RMI_ATTN_ACTIVE_LOW = 0,
RMI_ATTN_ACTIVE_HIGH = 1
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 08/11] Input: synaptics-rmi4 - f11: use the unified input node if available

2015-06-23 Thread Benjamin Tissoires
Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_f11.c | 60 ++--
 1 file changed, 35 insertions(+), 25 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index c3b757b..061530a 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -34,7 +34,6 @@
 #define DEFAULT_MAX_ABS_MT_ORIENTATION 1
 #define DEFAULT_MIN_ABS_MT_TRACKING_ID 1
 #define DEFAULT_MAX_ABS_MT_TRACKING_ID 10
-#define NAME_BUFFER_SIZE 256
 #define FUNCTION_NUMBER 0x11
 
 /** A note about RMI4 F11 register structure.
@@ -518,6 +517,7 @@ struct f11_2d_sensor {
u32 type_a; /* boolean but debugfs API requires u32 */
enum rmi_f11_sensor_type sensor_type;
struct input_dev *input;
+   bool unified_input;
struct rmi_function *fn;
char input_phys[NAME_BUFFER_SIZE];
u8 report_abs;
@@ -737,7 +737,8 @@ static void rmi_f11_finger_handler(struct f11_data *f11,
}
 
input_mt_sync_frame(sensor-input);
-   input_sync(sensor-input);
+   if (!sensor-unified_input)
+   input_sync(sensor-input);
 }
 
 static int f11_2d_construct_data(struct f11_2d_sensor *sensor)
@@ -1373,35 +1374,42 @@ static int rmi_f11_initialize(struct rmi_function *fn)
 static int rmi_f11_register_devices(struct rmi_function *fn)
 {
struct rmi_device *rmi_dev = fn-rmi_dev;
+   struct rmi_driver_data *drv_data = dev_get_drvdata(rmi_dev-dev);
struct f11_data *f11 = dev_get_drvdata(fn-dev);
struct input_dev *input_dev;
struct rmi_driver *driver = rmi_dev-driver;
struct f11_2d_sensor *sensor = f11-sensor;
int rc;
 
-   input_dev = input_allocate_device();
+   if (!drv_data-input) {
+   input_dev = input_allocate_device();
+   } else {
+   input_dev = drv_data-input;
+   sensor-unified_input = true;
+   }
if (!input_dev) {
rc = -ENOMEM;
goto error_unregister;
}
 
sensor-input = input_dev;
-   if (driver-set_input_params) {
-   rc = driver-set_input_params(rmi_dev, input_dev);
-   if (rc  0) {
-   dev_err(fn-dev,
-   %s: Error in setting input device.\n,
-   __func__);
-   goto error_unregister;
+
+   if (!sensor-unified_input) {
+   if (driver-set_input_params) {
+   rc = driver-set_input_params(rmi_dev, input_dev);
+   if (rc  0) {
+   dev_err(fn-dev,
+   %s: Error in setting input device.\n,
+   __func__);
+   goto error_unregister;
+   }
}
+   sprintf(sensor-input_phys, %s.abs/input0,
+   dev_name(fn-dev));
+   input_dev-phys = sensor-input_phys;
+   input_dev-dev.parent = rmi_dev-dev;
}
-   sprintf(sensor-input_phys, %s.abs/input0,
-   dev_name(fn-dev));
-   input_dev-phys = sensor-input_phys;
-   input_dev-dev.parent = rmi_dev-dev;
-   input_set_drvdata(input_dev, f11);
 
-   set_bit(EV_SYN, input_dev-evbit);
set_bit(EV_ABS, input_dev-evbit);
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
 
@@ -1413,19 +1421,21 @@ static int rmi_f11_register_devices(struct rmi_function 
*fn)
set_bit(REL_X, input_dev-relbit);
set_bit(REL_Y, input_dev-relbit);
}
-   rc = input_register_device(input_dev);
-   if (rc) {
-   input_free_device(input_dev);
-   sensor-input = NULL;
-   goto error_unregister;
+   if (!sensor-unified_input) {
+   rc = input_register_device(input_dev);
+   if (rc) {
+   input_free_device(input_dev);
+   sensor-input = NULL;
+   goto error_unregister;
+   }
}
 
return 0;
 
 error_unregister:
-   if (f11-sensor.input) {
-   input_unregister_device(f11-sensor.input);
-   f11-sensor.input = NULL;
+   if (!sensor-unified_input  sensor-input) {
+   input_unregister_device(sensor-input);
+   sensor-input = NULL;
}
 
return rc;
@@ -1525,7 +1535,7 @@ static void rmi_f11_remove(struct rmi_function *fn)
 {
struct f11_data *f11 = dev_get_drvdata(fn-dev);
 
-   if (f11-sensor.input)
+   if (!f11-sensor.unified_input  f11-sensor.input)
input_unregister_device(f11-sensor.input);
 }
 
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  

[PATCH 10/11] Input: synaptics-rmi4 - f11: allow the top software button property to be set

2015-06-23 Thread Benjamin Tissoires
Currently, in PS/2 we only have the PNPIds list to detect the property.
Unfortunately, it looks like the information is not embeded in the RMI4
protocol either, so allow the Top software buttons property to be set
in the platform data.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_f11.c | 5 +
 include/linux/rmi.h  | 3 +++
 2 files changed, 8 insertions(+)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 77a18aa..50df7a1 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -515,6 +515,7 @@ struct f11_2d_sensor {
int pkt_size;
u8 sensor_index;
u32 type_a; /* boolean but debugfs API requires u32 */
+   bool topbuttonpad;
enum rmi_f11_sensor_type sensor_type;
struct input_dev *input;
bool unified_input;
@@ -1285,6 +1286,7 @@ static int rmi_f11_initialize(struct rmi_function *fn)
sensor-axis_align =
pdata-f11_sensor_data-axis_align;
sensor-type_a = pdata-f11_sensor_data-type_a;
+   sensor-topbuttonpad = pdata-f11_sensor_data-topbuttonpad;
 
if (sensor-sens_query.has_physical_props) {
sensor-x_mm = sensor-sens_query.x_sensor_size_mm;
@@ -1409,6 +1411,9 @@ static int rmi_f11_register_devices(struct rmi_function 
*fn)
if (sensor-report_abs)
f11_set_abs_params(fn, f11);
 
+   if (sensor-topbuttonpad)
+   set_bit(INPUT_PROP_TOPBUTTONPAD, input_dev-propbit);
+
if (sensor-report_rel) {
set_bit(EV_REL, input_dev-evbit);
set_bit(REL_X, input_dev-relbit);
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
index b771f41..4ffe9fe 100644
--- a/include/linux/rmi.h
+++ b/include/linux/rmi.h
@@ -93,6 +93,8 @@ enum rmi_f11_sensor_type {
  * available.
  * @disable_report_mask - Force data to not be reported even if it is supported
  * by the firware.
+ * @topbuttonpad - Used with the 5 buttons touchpads found on the Lenovo 40
+ * series
  */
 struct rmi_f11_sensor_data {
struct rmi_f11_2d_axis_alignment axis_align;
@@ -101,6 +103,7 @@ struct rmi_f11_sensor_data {
int x_mm;
int y_mm;
int disable_report_mask;
+   bool topbuttonpad;
 };
 
 /**
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 05/11] Input: synaptics-rmi4 - call rmi_driver_process_config_requests in enable_sensor

2015-06-23 Thread Benjamin Tissoires
The SMBus devices have their IRQs disabled after a reset. We need to
configure them by calling rmi_driver_process_config_request() when
enabling the sensor.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_driver.c | 78 ++---
 drivers/input/rmi4/rmi_f11.c|  4 +++
 2 files changed, 45 insertions(+), 37 deletions(-)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index fe5f2f9..264bc62 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -136,42 +136,6 @@ static void disable_sensor(struct rmi_device *rmi_dev)
data-enabled = false;
 }
 
-static int enable_sensor(struct rmi_device *rmi_dev)
-{
-   struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);
-   struct rmi_transport_dev *xport;
-   int retval = 0;
-
-   if (data-enabled)
-   return 0;
-
-   if (rmi_dev-xport-ops-enable_device) {
-   retval = rmi_dev-xport-ops-enable_device(rmi_dev-xport);
-   if (retval)
-   return retval;
-   }
-
-   xport = rmi_dev-xport;
-   if (data-irq) {
-   retval = request_threaded_irq(data-irq,
-   xport-hard_irq ? xport-hard_irq : NULL,
-   xport-irq_thread ?
-   xport-irq_thread : rmi_irq_thread,
-   data-irq_flags,
-   dev_name(rmi_dev-dev), xport);
-   if (retval)
-   return retval;
-   } else if (data-polling) {
-   retval = enable_polling(rmi_dev);
-   if (retval  0)
-   return retval;
-   }
-
-   data-enabled = true;
-
-   return rmi_process_interrupt_requests(rmi_dev);
-}
-
 static void rmi_free_function_list(struct rmi_device *rmi_dev)
 {
struct rmi_function *fn, *tmp;
@@ -318,6 +282,46 @@ int rmi_process_interrupt_requests(struct rmi_device 
*rmi_dev)
 }
 EXPORT_SYMBOL_GPL(rmi_process_interrupt_requests);
 
+static int enable_sensor(struct rmi_device *rmi_dev)
+{
+   struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);
+   struct rmi_transport_dev *xport;
+   int retval = 0;
+
+   if (data-enabled)
+   return 0;
+
+   if (rmi_dev-xport-ops-enable_device) {
+   retval = rmi_dev-xport-ops-enable_device(rmi_dev-xport);
+   if (retval)
+   return retval;
+   }
+
+   retval = rmi_driver_process_config_requests(rmi_dev);
+   if (retval  0)
+   return retval;
+
+   xport = rmi_dev-xport;
+   if (data-irq) {
+   retval = request_threaded_irq(data-irq,
+   xport-hard_irq ? xport-hard_irq : NULL,
+   xport-irq_thread ?
+   xport-irq_thread : rmi_irq_thread,
+   data-irq_flags,
+   dev_name(rmi_dev-dev), xport);
+   if (retval)
+   return retval;
+   } else if (data-polling) {
+   retval = enable_polling(rmi_dev);
+   if (retval  0)
+   return retval;
+   }
+
+   data-enabled = true;
+
+   return rmi_process_interrupt_requests(rmi_dev);
+}
+
 /**
  * rmi_driver_set_input_params - set input device id and other data.
  *
@@ -960,7 +964,7 @@ static int rmi_driver_probe(struct device *dev)
 
if (data-f01_container-dev.driver) {
/* Driver already bound, so enable ATTN now. */
-   enable_sensor(rmi_dev);
+   return enable_sensor(rmi_dev);
}
 
return 0;
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 4bdf4a5..99d6181 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1440,9 +1440,13 @@ static int rmi_f11_config(struct rmi_function *fn)
 
if (!sensor-report_abs)
drv-clear_irq_bits(fn-rmi_dev, f11-abs_mask);
+   else
+   drv-set_irq_bits(fn-rmi_dev, f11-abs_mask);
 
if (!sensor-report_rel)
drv-clear_irq_bits(fn-rmi_dev, f11-rel_mask);
+   else
+   drv-set_irq_bits(fn-rmi_dev, f11-rel_mask);
 
rc = f11_write_control_regs(fn, f11-sensor.sens_query,
   f11-dev_controls, fn-fd.query_base_addr);
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Input :Optimize input_dev_release_keys function

2015-06-23 Thread Anshul Garg
From: Anshul Garg aksgarg1...@gmail.com

input_dev_release_keys : Use for_each_set_bit instead
of testing every bit upto KEY_MAX as it is more clean
and more optimized.

input_estimate_events_per_packet : Use bitmap_weight
to get set bits count for EV_REL type instead of using
loop and also use for_each_set_bit for EV_ABS event for
more optimized code.

Signed-off-by: Anshul Garg aksgarg1...@gmail.com
---
 drivers/input/input.c |   28 ++--
 1 file changed, 10 insertions(+), 18 deletions(-)

diff --git a/drivers/input/input.c b/drivers/input/input.c
index e0b7b8e..9459f8b 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -682,12 +682,9 @@ static void input_dev_release_keys(struct input_dev *dev)
int code;
 
if (is_event_supported(EV_KEY, dev-evbit, EV_MAX)) {
-   for (code = 0; code = KEY_MAX; code++) {
-   if (is_event_supported(code, dev-keybit, KEY_MAX) 
-   __test_and_clear_bit(code, dev-key)) {
-   input_pass_event(dev, EV_KEY, code, 0);
-   }
-   }
+   for_each_set_bit(code, dev-keybit, KEY_MAX)
+   input_pass_event(dev, EV_KEY, code, 0);
+   memset(dev-keybit, 0, sizeof(dev-keybit));
input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
}
 }
@@ -1986,21 +1983,16 @@ static unsigned int 
input_estimate_events_per_packet(struct input_dev *dev)
events = mt_slots + 1; /* count SYN_MT_REPORT and SYN_REPORT */
 
if (test_bit(EV_ABS, dev-evbit)) {
-   for (i = 0; i  ABS_CNT; i++) {
-   if (test_bit(i, dev-absbit)) {
-   if (input_is_mt_axis(i))
-   events += mt_slots;
-   else
-   events++;
-   }
+   for_each_set_bit(i, dev-absbit, ABS_CNT) {
+   if (input_is_mt_axis(i))
+   events += mt_slots;
+   else
+   events++;
}
}
 
-   if (test_bit(EV_REL, dev-evbit)) {
-   for (i = 0; i  REL_CNT; i++)
-   if (test_bit(i, dev-relbit))
-   events++;
-   }
+   if (test_bit(EV_REL, dev-evbit))
+   events += bitmap_weight(dev-relbit, REL_CNT);
 
/* Make room for KEY and MSC events */
events += 7;
-- 
1.7.9.5


---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v5 1/2] dt: add cap11xx LED documentation

2015-06-23 Thread Dmitry Torokhov
On Tue, Jun 23, 2015 at 11:24:42AM -0700, Matt Ranostay wrote:
 On Tue, Jun 23, 2015 at 11:07 AM, Dmitry Torokhov
 dmitry.torok...@gmail.com wrote:
  On Tue, Jun 23, 2015 at 10:23:57AM -0700, Matt Ranostay wrote:
  On Tue, Jun 23, 2015 at 1:36 AM, Jacek Anaszewski
  j.anaszew...@samsung.com wrote:
   On 06/22/2015 07:59 PM, Dmitry Torokhov wrote:
  
   On Wed, Jun 17, 2015 at 08:58:16PM -0700, Matt Ranostay wrote:
  
   Signed-off-by: Matt Ranostay mranos...@gmail.com
   ---
 .../devicetree/bindings/input/cap11xx.txt  | 25
   ++
 1 file changed, 25 insertions(+)
  
   diff --git a/Documentation/devicetree/bindings/input/cap11xx.txt
   b/Documentation/devicetree/bindings/input/cap11xx.txt
   index 7d0a300..09cdc43 100644
   --- a/Documentation/devicetree/bindings/input/cap11xx.txt
   +++ b/Documentation/devicetree/bindings/input/cap11xx.txt
   @@ -38,6 +38,11 @@ Optional properties:
   defaults. The array must have exactly 
   six
   entries.
  
   +   linux,led-brightness:   Defines the ON brightness when the
   optional LED
   +   functionality is used. Valid values are
   1-15.
   +   By default a value of 15 is set.
  
  
   Please mention the device does not allow controlling brightness of leds
   individually and that is why this property is at device level, not
   individual led level.
  
  
   I've just noticed that we have drivers/leds/leds-netxbig.c driver, which
   also doesn't allow controlling the LEDs on extension board individually,
   but it still does allow changing their brightness. I am leaning towards
   allowing this also for this driver and adding similar comment in the
   source code like at the line 218 of the aforementioned driver.
   As a result this property wouldn't be required.
  
 
  Ok that should be pretty simple to do. But seems kind weird to have
  each led channel to be changing the brightness of all.  Wouldn't the
  brightness sysfs entries of the other led channels be showing
  incorrect values?
 
  I agree, this is kind of weird. Maybe we should have a device-specific
  attribute (on the platform device level) that allows controlling overall
  brightness, but I think LEDs should be just on/off with max brightness
  of 1. Userspace should not have to be aware about the fact that on that
  particular device LEDs are not completely independent as far as their
  brightness goes.
 
 So should I drop the devicetree part of the patch in v6?

I think so. Let's have the device come up with LEDs brightness at default
value and then users can adjust it as they need via sysfs.

Thanks.

-- 
Dmitry
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 09/11] Input: synaptics-rmi4 - f11: clean up rmi_f11_finger_handler

2015-06-23 Thread Benjamin Tissoires
abs_bit and rel_bits should not be computed at each iteration of the for
loop.
finger_press_count is unused.
Break out rmi_f11_parse_finger_state in its own function.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_f11.c | 33 +
 1 file changed, 13 insertions(+), 20 deletions(-)

diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 061530a..77a18aa 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -695,43 +695,36 @@ static void rmi_f11_abs_pos_report(struct f11_data *f11,
input_mt_sync(input);
 }
 
+static inline u8 rmi_f11_parse_finger_state(const u8 *f_state, u8 n_finger)
+{
+   return (f_state[n_finger / 4]  (2 * (n_finger % 4))) 
+   FINGER_STATE_MASK;
+}
+
 static void rmi_f11_finger_handler(struct f11_data *f11,
   struct f11_2d_sensor *sensor,
   unsigned long *irq_bits, int num_irq_regs)
 {
const u8 *f_state = sensor-data.f_state;
u8 finger_state;
-   u8 finger_pressed_count;
u8 i;
 
-   int rel_bits;
-   int abs_bits;
+   int abs_bits = bitmap_and(f11-result_bits, irq_bits, f11-abs_mask,
+ num_irq_regs * 8);
+   int rel_bits = bitmap_and(f11-result_bits, irq_bits, f11-rel_mask,
+ num_irq_regs * 8);
 
-   for (i = 0, finger_pressed_count = 0; i  sensor-nbr_fingers; i++) {
+   for (i = 0; i  sensor-nbr_fingers; i++) {
/* Possible of having 4 fingers per f_statet register */
-   finger_state = (f_state[i / 4]  (2 * (i % 4))) 
-   FINGER_STATE_MASK;
-   switch (finger_state) {
-   case F11_RESERVED:
+   finger_state = rmi_f11_parse_finger_state(f_state, i);
+   if (finger_state == F11_RESERVED) {
pr_err(Invalid finger state[%d]: 0x%02x, i, 
finger_state);
continue;
-
-   case F11_PRESENT:
-   case F11_INACCURATE:
-   finger_pressed_count++;
-   break;
-
-   case F11_NO_FINGER:
-   break;
}
 
-   abs_bits = bitmap_and(f11-result_bits, irq_bits, f11-abs_mask,
- num_irq_regs * 8);
if (abs_bits)
rmi_f11_abs_pos_report(f11, sensor, finger_state, i);
 
-   rel_bits = bitmap_and(f11-result_bits, irq_bits, f11-rel_mask,
- num_irq_regs * 8);
if (rel_bits)
rmi_f11_rel_pos_report(sensor, i);
}
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 02/11] Input: synaptics-rmi4 - add a common input device in rmi_driver

2015-06-23 Thread Benjamin Tissoires
When .unified_input is set to true in the platform data, the
functions should rely on the common input node created by rmi_driver
to forward events instead of having their own input node.

This node is named Synaptics PRODUCT_ID to be able to
differentiate the various models.

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/rmi_driver.c | 43 +
 drivers/input/rmi4/rmi_driver.h |  6 ++
 drivers/input/rmi4/rmi_f01.c|  7 +++
 include/linux/rmi.h |  2 ++
 4 files changed, 58 insertions(+)

diff --git a/drivers/input/rmi4/rmi_driver.c b/drivers/input/rmi4/rmi_driver.c
index b9db709..95f9386 100644
--- a/drivers/input/rmi4/rmi_driver.c
+++ b/drivers/input/rmi4/rmi_driver.c
@@ -310,6 +310,9 @@ static int process_interrupt_requests(struct rmi_device 
*rmi_dev)
if (entry-irq_mask)
process_one_interrupt(data, entry);
 
+   if (data-input)
+   input_sync(data-input);
+
return 0;
 }
 
@@ -330,6 +333,25 @@ static int rmi_driver_set_input_params(struct rmi_device 
*rmi_dev,
return 0;
 }
 
+static void rmi_driver_set_input_name(struct rmi_device *rmi_dev,
+   struct input_dev *input)
+{
+   struct rmi_driver_data *data = dev_get_drvdata(rmi_dev-dev);
+   char *device_name = rmi_f01_get_product_ID(data-f01_container);
+   char *name;
+
+   if (!device_name)
+   return;
+
+   name = devm_kasprintf(rmi_dev-dev, GFP_KERNEL,
+ Synaptics %s, device_name);
+   if (!name)
+   return;
+
+   input-name = name;
+}
+
+
 static int rmi_driver_set_irq_bits(struct rmi_device *rmi_dev,
   unsigned long *mask)
 {
@@ -720,6 +742,8 @@ static int rmi_driver_remove(struct device *dev)
const struct rmi_device_platform_data *pdata =
rmi_get_platform_data(rmi_dev);
 
+   if (data-input)
+   input_unregister_device(data-input);
disable_sensor(rmi_dev);
rmi_free_function_list(rmi_dev);
 
@@ -832,6 +856,15 @@ static int rmi_driver_probe(struct device *dev)
data-current_irq_mask  = irq_memory + size * 2;
data-new_irq_mask  = irq_memory + size * 3;
 
+   if (pdata-unified_input) {
+   data-input = input_allocate_device();
+   if (data-input) {
+   rmi_driver_set_input_params(rmi_dev, data-input);
+   sprintf(data-input_phys, %s/input0, dev_name(dev));
+   data-input-phys = data-input_phys;
+   }
+   }
+
irq_count = 0;
dev_dbg(dev, Creating functions.);
retval = rmi_scan_pdt(rmi_dev, irq_count, rmi_create_function);
@@ -866,6 +899,15 @@ static int rmi_driver_probe(struct device *dev)
mutex_init(data-suspend_mutex);
}
 
+   if (data-input) {
+   rmi_driver_set_input_name(rmi_dev, data-input);
+   if (input_register_device(data-input)) {
+   dev_err(dev, %s: Failed to register input device.\n,
+   __func__);
+   goto err_destroy_functions;
+   }
+   }
+
if (gpio_is_valid(pdata-attn_gpio)) {
static const char GPIO_LABEL[] = attn;
unsigned long gpio_flags = GPIOF_DIR_IN;
@@ -921,6 +963,7 @@ static int rmi_driver_probe(struct device *dev)
return 0;
 
 err_destroy_functions:
+   input_free_device(data-input);
rmi_free_function_list(rmi_dev);
kfree(irq_memory);
 err_free_mem:
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index dda564f..36ca34b 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -13,6 +13,7 @@
 #include linux/ctype.h
 #include linux/hrtimer.h
 #include linux/ktime.h
+#include linux/input.h
 #include rmi_bus.h
 
 #define RMI_DRIVER_VERSION 1.6
@@ -29,6 +30,8 @@
 
 #define RMI_PDT_PROPS_HAS_BSR 0x02
 
+#define NAME_BUFFER_SIZE 256
+
 struct rmi_driver_data {
struct list_head function_list;
 
@@ -49,6 +52,8 @@ struct rmi_driver_data {
unsigned long *current_irq_mask;
unsigned long *new_irq_mask;
struct mutex irq_mutex;
+   struct input_dev *input;
+   char input_phys[NAME_BUFFER_SIZE];
 
/* Following are used when polling. */
struct hrtimer poll_timer;
@@ -112,6 +117,7 @@ void rmi_unregister_physical_driver(void);
 
 int rmi_register_f01_handler(void);
 void rmi_unregister_f01_handler(void);
+char *rmi_f01_get_product_ID(struct rmi_function *fn);
 
 #ifdef CONFIG_RMI4_F11
 int rmi_register_f11_handler(void);
diff --git a/drivers/input/rmi4/rmi_f01.c b/drivers/input/rmi4/rmi_f01.c
index ee5f4a1..2d72dc8 100644
--- a/drivers/input/rmi4/rmi_f01.c
+++ b/drivers/input/rmi4/rmi_f01.c
@@ -176,6 

[PATCH 01/11] Input: synaptics-rmi4 - embed the function modules in rmi_core

2015-06-23 Thread Benjamin Tissoires
the function modules can not be auto-loaded by udev. So at boot, the
functions are not there and the device is not properly populated.
Force the functions to be embedded in rmi_core so that when the touchpad
is there, the functions are there too.

There is not much use of having the functions separate anyway

Signed-off-by: Benjamin Tissoires benjamin.tissoi...@redhat.com
---
 drivers/input/rmi4/Kconfig  |  5 +
 drivers/input/rmi4/Makefile |  2 +-
 drivers/input/rmi4/rmi_bus.c| 11 ++-
 drivers/input/rmi4/rmi_driver.h |  8 
 drivers/input/rmi4/rmi_f11.c| 10 +-
 5 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/drivers/input/rmi4/Kconfig b/drivers/input/rmi4/Kconfig
index d0c7b6e..5e3890e 100644
--- a/drivers/input/rmi4/Kconfig
+++ b/drivers/input/rmi4/Kconfig
@@ -37,7 +37,7 @@ config RMI4_I2C
  This feature is not currently available as a loadable module.
 
 config RMI4_F11
-   tristate RMI4 Function 11 (2D pointing)
+   bool RMI4 Function 11 (2D pointing)
depends on RMI4_CORE
help
  Say Y here if you want to add support for RMI4 function 11.
@@ -46,9 +46,6 @@ config RMI4_F11
  touchpads.  For sensors that support relative pointing, F11 also
  provides mouse input.
 
- To compile this driver as a module, choose M here: the
- module will be called rmi-f11.
-
 config RMI4_F11_PEN
bool RMI4 F11 Pen Support
depends on RMI4_F11
diff --git a/drivers/input/rmi4/Makefile b/drivers/input/rmi4/Makefile
index 5c6bad5..63bc595 100644
--- a/drivers/input/rmi4/Makefile
+++ b/drivers/input/rmi4/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_RMI4_CORE) += rmi_core.o
 rmi_core-y := rmi_bus.o rmi_driver.o rmi_f01.o
 
 # Function drivers
-obj-$(CONFIG_RMI4_F11) += rmi_f11.o
+rmi_core-$(CONFIG_RMI4_F11) += rmi_f11.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 6e0454a..ef2078a 100644
--- a/drivers/input/rmi4/rmi_bus.c
+++ b/drivers/input/rmi4/rmi_bus.c
@@ -383,15 +383,24 @@ static int __init rmi_bus_init(void)
goto err_unregister_bus;
}
 
+   error = rmi_register_f11_handler();
+   if (error) {
+   pr_err(%s: error registering the RMI F11 handler: %d\n,
+   __func__, error);
+   goto err_unregister_f01;
+   }
+
error = rmi_register_physical_driver();
if (error) {
pr_err(%s: error registering the RMI physical driver: %d\n,
__func__, error);
-   goto err_unregister_f01;
+   goto err_unregister_f11;
}
 
return 0;
 
+err_unregister_f11:
+   rmi_unregister_f11_handler();
 err_unregister_f01:
rmi_unregister_f01_handler();
 err_unregister_bus:
diff --git a/drivers/input/rmi4/rmi_driver.h b/drivers/input/rmi4/rmi_driver.h
index 34f7a7d..dda564f 100644
--- a/drivers/input/rmi4/rmi_driver.h
+++ b/drivers/input/rmi4/rmi_driver.h
@@ -113,4 +113,12 @@ void rmi_unregister_physical_driver(void);
 int rmi_register_f01_handler(void);
 void rmi_unregister_f01_handler(void);
 
+#ifdef CONFIG_RMI4_F11
+int rmi_register_f11_handler(void);
+void rmi_unregister_f11_handler(void);
+#else
+static inline int rmi_register_f11_handler(void) { return 0; }
+static inline void rmi_unregister_f11_handler(void) {}
+#endif
+
 #endif
diff --git a/drivers/input/rmi4/rmi_f11.c b/drivers/input/rmi4/rmi_f11.c
index 7af4f68..4bdf4a5 100644
--- a/drivers/input/rmi4/rmi_f11.c
+++ b/drivers/input/rmi4/rmi_f11.c
@@ -1537,7 +1537,15 @@ static struct rmi_function_handler rmi_f11_handler = {
.attention  = rmi_f11_attention,
 };
 
-module_rmi_driver(rmi_f11_handler);
+int __init rmi_register_f11_handler(void)
+{
+   return rmi_register_function_handler(rmi_f11_handler);
+}
+
+void rmi_unregister_f11_handler(void)
+{
+   rmi_unregister_function_handler(rmi_f11_handler);
+}
 
 MODULE_AUTHOR(Christopher Heiny che...@synaptics.com);
 MODULE_AUTHOR(Andrew Duggan adug...@synaptics.com);
-- 
2.4.3

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] touchscreen: sun4i-ts: Really fix A10 temperature reporting

2015-06-23 Thread Hans de Goede

Hi,

On 06/23/2015 05:06 PM, m.silentcr...@gmail.com wrote:

Hi Hans,

is it possible that this patch (and the parent commit Input: sun4i-ts - allow 
controlling filter and sensitivity via DT) has quite an adversial effect on other 
boards than the ones tested?

On my Lemaker Bananapi the temperature is now being reported as somwhere 
between -15°C to -10°C with the latest Kernel 4.1.0. These negative values are 
obviously way off. On Kernel 4.0.5 the temperature reading was usually around 
40°C. While that might not have been accurate either, it was at least plausible.


The temperature curve for the A20 SoC was not changed, if it did change then
you're using an old dtb file with a new kernel, you must always update your
dtb file together with the kernel.





Given that there is no Documentation and things seem quite board-specific, I 
really don't know how this could be improved, so I can merely report my 
observation.

Kind regards,

Timo


Am Montag, 9. März 2015 10:38:02 UTC+1 schrieb Hans de Goede:

The commit titled:
touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
contains a math error, the offset it uses is in degrees, but the actual code
applies the offset before multiplying by stepsize :|

Given that this is rather backwards (every math course ever thought applies
the multiplication before the offset for linear functions), this commit
fixes things by changing the code applying the offset to do the logical
thing, adjusting the offset for the other models accordingly.

This has been tested on an A10, A13, A20 and A31 to make sure everything really
is correct now.

Signed-off-by: Hans de Goede hdego...@redhat.com
---
Note if possible this commit should be squashed into the original
touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
commit as a fixup.
---
  drivers/input/touchscreen/sun4i-ts.c | 14 +++---
  1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/input/touchscreen/sun4i-ts.c 
b/drivers/input/touchscreen/sun4i-ts.c
index 66ccd5a..178d2ef 100644
--- a/drivers/input/touchscreen/sun4i-ts.c
+++ b/drivers/input/touchscreen/sun4i-ts.c
@@ -193,7 +193,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data *ts, 
long *temp)
if (ts-temp_data == -1)
return -EAGAIN;

-   *temp = (ts-temp_data - ts-temp_offset) * ts-temp_step;
+   *temp = ts-temp_data * ts-temp_step - ts-temp_offset;

return 0;
  }
@@ -255,17 +255,17 @@ static int sun4i_ts_probe(struct platform_device *pdev)
ts-ignore_fifo_data = true;
ts-temp_data = -1;
if (of_device_is_compatible(np, allwinner,sun6i-a31-ts)) {
-   /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
-   ts-temp_offset = 1626;
+   /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
+   ts-temp_offset = 271000;
ts-temp_step = 167;
} else if (of_device_is_compatible(np, allwinner,sun4i-a10-ts)) {
/*
 * The A10 temperature sensor has quite a wide spread, these
 * parameters are based on the averaging of the calibration
 * results of 4 completely different boards, with a spread of
-* temp_step from 96 - 170 and temp_offset from 1758 - 3310.
+* temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
 */
-   ts-temp_offset = 2570;
+   ts-temp_offset = 257000;
ts-temp_step = 133;
} else {
/*
@@ -273,13 +273,13 @@ static int sun4i_ts_probe(struct platform_device *pdev)
 * the temperature. The formula used here is from the AXP209,
 * which is designed by X-Powers, an affiliate of Allwinner:
 *
-* temperature = -144.7 + (value * 0.1)
+* temperature (C) = (value * 0.1) - 144.7
 *
 * Allwinner does not have any documentation whatsoever for
 * this hardware. Moreover, it is claimed that the sensor
 * is inaccurate and cannot work properly.
 */
-   ts-temp_offset = 1447;
+   ts-temp_offset = 144700;
ts-temp_step = 100;
}

--
2.3.1




Regards,

Hans
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] touchscreen: sun4i-ts: Really fix A10 temperature reporting

2015-06-23 Thread m . silentcreek
Hi,

Am Dienstag, 23. Juni 2015 21:46:25 UTC+2 schrieb Hans de Goede:
 Hi,
 
 On 06/23/2015 05:06 PM, m.silentcr...@gmail.com wrote:
  Hi Hans,
 
  is it possible that this patch (and the parent commit Input: sun4i-ts - 
  allow controlling filter and sensitivity via DT) has quite an adversial 
  effect on other boards than the ones tested?
 
  On my Lemaker Bananapi the temperature is now being reported as somwhere 
  between -15°C to -10°C with the latest Kernel 4.1.0. These negative values 
  are obviously way off. On Kernel 4.0.5 the temperature reading was usually 
  around 40°C. While that might not have been accurate either, it was at 
  least plausible.
 
 The temperature curve for the A20 SoC was not changed, if it did change then
 you're using an old dtb file with a new kernel, you must always update your
 dtb file together with the kernel.

I always compile the dts that comes with the kernel tree from scratch. So this 
is up to date. I guess I have to dig in deeper then what caused that change. 
Any other hint where to look for?


 
 
 
 
  Given that there is no Documentation and things seem quite board-specific, 
  I really don't know how this could be improved, so I can merely report my 
  observation.
 
  Kind regards,
 
  Timo
 
 
  Am Montag, 9. März 2015 10:38:02 UTC+1 schrieb Hans de Goede:
  The commit titled:
  touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
  contains a math error, the offset it uses is in degrees, but the actual 
  code
  applies the offset before multiplying by stepsize :|
 
  Given that this is rather backwards (every math course ever thought applies
  the multiplication before the offset for linear functions), this commit
  fixes things by changing the code applying the offset to do the logical
  thing, adjusting the offset for the other models accordingly.
 
  This has been tested on an A10, A13, A20 and A31 to make sure everything 
  really
  is correct now.
 
  Signed-off-by: Hans de Goede hdego...@redhat.com
  ---
  Note if possible this commit should be squashed into the original
  touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
  commit as a fixup.
  ---
drivers/input/touchscreen/sun4i-ts.c | 14 +++---
1 file changed, 7 insertions(+), 7 deletions(-)
 
  diff --git a/drivers/input/touchscreen/sun4i-ts.c 
  b/drivers/input/touchscreen/sun4i-ts.c
  index 66ccd5a..178d2ef 100644
  --- a/drivers/input/touchscreen/sun4i-ts.c
  +++ b/drivers/input/touchscreen/sun4i-ts.c
  @@ -193,7 +193,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data 
  *ts, long *temp)
 if (ts-temp_data == -1)
 return -EAGAIN;
 
  -  *temp = (ts-temp_data - ts-temp_offset) * ts-temp_step;
  +  *temp = ts-temp_data * ts-temp_step - ts-temp_offset;
 
 return 0;
}
  @@ -255,17 +255,17 @@ static int sun4i_ts_probe(struct platform_device 
  *pdev)
 ts-ignore_fifo_data = true;
 ts-temp_data = -1;
 if (of_device_is_compatible(np, allwinner,sun6i-a31-ts)) {
  -  /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
  -  ts-temp_offset = 1626;
  +  /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
  +  ts-temp_offset = 271000;
 ts-temp_step = 167;
 } else if (of_device_is_compatible(np, allwinner,sun4i-a10-ts)) {
 /*
  * The A10 temperature sensor has quite a wide spread, these
  * parameters are based on the averaging of the calibration
  * results of 4 completely different boards, with a spread of
  -   * temp_step from 96 - 170 and temp_offset from 1758 - 3310.
  +   * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
  */
  -  ts-temp_offset = 2570;
  +  ts-temp_offset = 257000;
 ts-temp_step = 133;
 } else {
 /*
  @@ -273,13 +273,13 @@ static int sun4i_ts_probe(struct platform_device 
  *pdev)
  * the temperature. The formula used here is from the AXP209,
  * which is designed by X-Powers, an affiliate of Allwinner:
  *
  -   * temperature = -144.7 + (value * 0.1)
  +   * temperature (C) = (value * 0.1) - 144.7
  *
  * Allwinner does not have any documentation whatsoever for
  * this hardware. Moreover, it is claimed that the sensor
  * is inaccurate and cannot work properly.
  */
  -  ts-temp_offset = 1447;
  +  ts-temp_offset = 144700;
 ts-temp_step = 100;
 }
 
  --
  2.3.1
 
 
 Regards,
 
 Hans

Thanks,

Timo

Re: [PATCH] touchscreen: sun4i-ts: Really fix A10 temperature reporting

2015-06-23 Thread m . silentcreek
Hi again,

Am Dienstag, 23. Juni 2015 21:46:25 UTC+2 schrieb Hans de Goede:
 Hi,
 
 On 06/23/2015 05:06 PM, m.silentcr...@gmail.com wrote:
  Hi Hans,
 
  is it possible that this patch (and the parent commit Input: sun4i-ts - 
  allow controlling filter and sensitivity via DT) has quite an adversial 
  effect on other boards than the ones tested?
 
  On my Lemaker Bananapi the temperature is now being reported as somwhere 
  between -15°C to -10°C with the latest Kernel 4.1.0. These negative values 
  are obviously way off. On Kernel 4.0.5 the temperature reading was usually 
  around 40°C. While that might not have been accurate either, it was at 
  least plausible.
 
 The temperature curve for the A20 SoC was not changed, if it did change then
 you're using an old dtb file with a new kernel, you must always update your
 dtb file together with the kernel.

I just checked the diff for Linux 4.0 and 4.1 and noticed that sun7i-a20.dtsi 
in fact has not changed. Is it possible that something that should have been 
merged got delayed?

I looked in Maxime's tree dt-for-4.2 and found this patch that looks like it 
could be related: 
https://git.kernel.org/cgit/linux/kernel/git/mripard/linux.git/commit/?h=sunxi/dt-for-4.2id=8bf1b9b3d90194a174493febc731f7783f2adf1a

 
 
 
 
  Given that there is no Documentation and things seem quite board-specific, 
  I really don't know how this could be improved, so I can merely report my 
  observation.
 
  Kind regards,
 
  Timo
 
 
  Am Montag, 9. März 2015 10:38:02 UTC+1 schrieb Hans de Goede:
  The commit titled:
  touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
  contains a math error, the offset it uses is in degrees, but the actual 
  code
  applies the offset before multiplying by stepsize :|
 
  Given that this is rather backwards (every math course ever thought applies
  the multiplication before the offset for linear functions), this commit
  fixes things by changing the code applying the offset to do the logical
  thing, adjusting the offset for the other models accordingly.
 
  This has been tested on an A10, A13, A20 and A31 to make sure everything 
  really
  is correct now.
 
  Signed-off-by: Hans de Goede hdego...@redhat.com
  ---
  Note if possible this commit should be squashed into the original
  touchscreen: sun4i-ts: A10 (sun4i) has a different temperature curve
  commit as a fixup.
  ---
drivers/input/touchscreen/sun4i-ts.c | 14 +++---
1 file changed, 7 insertions(+), 7 deletions(-)
 
  diff --git a/drivers/input/touchscreen/sun4i-ts.c 
  b/drivers/input/touchscreen/sun4i-ts.c
  index 66ccd5a..178d2ef 100644
  --- a/drivers/input/touchscreen/sun4i-ts.c
  +++ b/drivers/input/touchscreen/sun4i-ts.c
  @@ -193,7 +193,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data 
  *ts, long *temp)
 if (ts-temp_data == -1)
 return -EAGAIN;
 
  -  *temp = (ts-temp_data - ts-temp_offset) * ts-temp_step;
  +  *temp = ts-temp_data * ts-temp_step - ts-temp_offset;
 
 return 0;
}
  @@ -255,17 +255,17 @@ static int sun4i_ts_probe(struct platform_device 
  *pdev)
 ts-ignore_fifo_data = true;
 ts-temp_data = -1;
 if (of_device_is_compatible(np, allwinner,sun6i-a31-ts)) {
  -  /* Allwinner SDK has temperature = -271 + (value / 6) (C) */
  -  ts-temp_offset = 1626;
  +  /* Allwinner SDK has temperature (C) = (value / 6) - 271 */
  +  ts-temp_offset = 271000;
 ts-temp_step = 167;
 } else if (of_device_is_compatible(np, allwinner,sun4i-a10-ts)) {
 /*
  * The A10 temperature sensor has quite a wide spread, these
  * parameters are based on the averaging of the calibration
  * results of 4 completely different boards, with a spread of
  -   * temp_step from 96 - 170 and temp_offset from 1758 - 3310.
  +   * temp_step from 0.096 - 0.170 and temp_offset from 176 - 331.
  */
  -  ts-temp_offset = 2570;
  +  ts-temp_offset = 257000;
 ts-temp_step = 133;
 } else {
 /*
  @@ -273,13 +273,13 @@ static int sun4i_ts_probe(struct platform_device 
  *pdev)
  * the temperature. The formula used here is from the AXP209,
  * which is designed by X-Powers, an affiliate of Allwinner:
  *
  -   * temperature = -144.7 + (value * 0.1)
  +   * temperature (C) = (value * 0.1) - 144.7
  *
  * Allwinner does not have any documentation whatsoever for
  * this hardware. Moreover, it is claimed that the sensor
  * is inaccurate and cannot work properly.
  */
  -  ts-temp_offset = 1447;
  +  ts-temp_offset = 144700;
 ts-temp_step = 100;
 }
 
  --
  2.3.1
 
 
 Regards,
 
 Hans

Regards,

Timo

Re: [PATCH] input: zforce_ts: add DT support for reset GPIO polarity

2015-06-23 Thread Dirk Behme

On 17.06.2015 01:57, Dmitry Torokhov wrote:

On Mon, Jun 15, 2015 at 07:54:25AM +0200, Dirk Behme wrote:

From: Knut Wohlrab knut.wohl...@de.bosch.com

According to

Documentation/devicetree/bindings/input/touchscreen/zforce_ts.txt

the RST GPIO is supposed to provide a polarity flag parameter

gpios = GPIO_BANK GPIO_NUMBER GPIO_POLARITY

with GPIO_POLARITY

reset active low  = 1 (GPIO_ACTIVE_LOW)
reset active high = 0 (GPIO_ACTIVE_HIGH)

Example for GPIO_ACTIVE_LOW (1) reset GPIO:

zforce_ts@50 { /* Neonode zForce I2C */
compatible = neonode,zforce-ts;
...
gpios = gpio6 14 GPIO_ACTIVE_HIGH, /* INT */
gpio1 29 GPIO_ACTIVE_LOW; /* RST */
...
};

Add the missing polarity flag evaluation to the driver.

Signed-off-by: Knut Wohlrab knut.wohl...@de.bosch.com
Signed-off-by: Oleksij Rempel external.oleksij.rem...@de.bosch.com
Signed-off-by: Dirk Behme dirk.be...@de.bosch.com
---
  drivers/input/touchscreen/zforce_ts.c   | 27 +++
  include/linux/platform_data/zforce_ts.h |  3 +++
  2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/drivers/input/touchscreen/zforce_ts.c 
b/drivers/input/touchscreen/zforce_ts.c
index 19880c7..125311d 100644
--- a/drivers/input/touchscreen/zforce_ts.c
+++ b/drivers/input/touchscreen/zforce_ts.c
@@ -162,6 +162,20 @@ static int zforce_command(struct zforce_ts *ts, u8 cmd)
return 0;
  }

+static void zforce_reset_assert(struct zforce_ts *ts)
+{
+   const struct zforce_ts_platdata *pdata = ts-pdata;
+
+   gpio_set_value(pdata-gpio_rst, pdata-reset_active_low ? 0 : 1);


Instead of doing this I'd rather we converted the driver to use gpiod
that handles polarity automatically.



Thanks, we'll look into that.

Just to understand correctly: Converting this driver to gpiod will be an 
additional patch on top of this patch as it doesn't change any 
functionality provided by this patch, but does some clean up. Correct?



Best regards

Dirk
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] pcf8574_keypad: use request_devm_threaded_irq

2015-06-23 Thread Michael Grzeschik
On Mon, Jun 22, 2015 at 01:55:52PM -0700, Dmitry Torokhov wrote:
 On Fri, Jun 19, 2015 at 12:35:54PM +0200, Michael Grzeschik wrote:
  We can use the devres API here. Remove the extra cleanup codepath.
 
 We could, but not like that (hint: what is the order of releasing
 resources with your patch?). Also, calling free_irq() on IRQ requested
 by devm_* is not quite valid. Did you test the patch, especially the
 remove portion?

Doh, thanks for the hints. I will send v2.

Michael

 
  
  Signed-off-by: Michael Grzeschik m.grzesc...@pengutronix.de
  ---
   drivers/input/misc/pcf8574_keypad.c | 7 +++
   1 file changed, 3 insertions(+), 4 deletions(-)
  
  diff --git a/drivers/input/misc/pcf8574_keypad.c 
  b/drivers/input/misc/pcf8574_keypad.c
  index 97f711a..62fcf36 100644
  --- a/drivers/input/misc/pcf8574_keypad.c
  +++ b/drivers/input/misc/pcf8574_keypad.c
  @@ -131,7 +131,8 @@ static int pcf8574_kp_probe(struct i2c_client *client, 
  const struct i2c_device_i
   
  lp-laststate = read_state(lp);
   
  -   ret = request_threaded_irq(client-irq, NULL, pcf8574_kp_irq_handler,
  +   ret = devm_request_threaded_irq(client-dev, client-irq,
  +  NULL, pcf8574_kp_irq_handler,
 IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 DRV_NAME, lp);
  if (ret) {
  @@ -142,14 +143,12 @@ static int pcf8574_kp_probe(struct i2c_client 
  *client, const struct i2c_device_i
  ret = input_register_device(idev);
  if (ret) {
  dev_err(client-dev, input_register_device() failed\n);
  -   goto fail_free_irq;
  +   goto fail_free_device;
  }
   
  i2c_set_clientdata(client, lp);
  return 0;
   
  - fail_free_irq:
  -   free_irq(client-irq, lp);
fail_free_device:
  input_free_device(idev);
fail_allocate:
  -- 
  2.1.4
  
 
 Thanks.
 
 -- 
 Dmitry
 

-- 
Pengutronix e.K.   | |
Industrial Linux Solutions | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |
--
To unsubscribe from this list: send the line unsubscribe linux-input in


Re: [PATCH v5 2/2] cap11xx: add LED support

2015-06-23 Thread Jacek Anaszewski

On 06/22/2015 08:08 PM, Dmitry Torokhov wrote:
[...]


+
+   for_each_child_of_node(node, child) {
+   led-cdev.name =
+   of_get_property(child, label, NULL) ? : child-name;
+   led-cdev.default_trigger =
+   of_get_property(child, linux,default-trigger, NULL);


Hmm, we do not have standard LEDs fwnode parser? Maybe we should have
one.


We don't have one. That's something to be added.

--
Best Regards,
Jacek Anaszewski
--
To unsubscribe from this list: send the line unsubscribe linux-input in


Re: [linux-sunxi] Re: [PATCH] input: axp20x-pek: Fix reporting button state as inverted

2015-06-23 Thread Chen-Yu Tsai
On Tue, Jun 23, 2015 at 5:30 AM, Dmitry Torokhov
dmitry.torok...@gmail.com wrote:
 On Sun, Jun 14, 2015 at 12:42:21PM +0200, Hans de Goede wrote:
 Currently we are reporting the button state as inverted on all boards with
 an axp209 pmic, tested on a ba10-tvbox, bananapi, bananapro, cubietruck and
 utoo-p66 tablet.

 The axp209 datasheet clearly states that the power button must be connected
 between the PWRON key and ground. Which means that on a press we will get
 a falling edge (dbf) irq not a rising one, and likewise on release we will
 get a rising edge (dbr) irq, not a falling one.

 This commit swaps the check for the 2 irqs fixing the inverted reporting of
 the power button state.

 Signed-off-by: Hans de Goede hdego...@redhat.com

 Carlo, Chen-Yu, could you please give this patch a spin and let us know
 if it works on your boards?

I've not actually tested this patch on my boards, but I can confirm that
the original code had the state inverted, by checking /proc/interrupts
counters, before and after releasing the power button.

Acked-by: Chen-Yu Tsai w...@csie.org

 Thanks!

 ---
  drivers/input/misc/axp20x-pek.c | 8 ++--
  1 file changed, 6 insertions(+), 2 deletions(-)

 diff --git a/drivers/input/misc/axp20x-pek.c 
 b/drivers/input/misc/axp20x-pek.c
 index f1c8447..10e140a 100644
 --- a/drivers/input/misc/axp20x-pek.c
 +++ b/drivers/input/misc/axp20x-pek.c
 @@ -167,9 +167,13 @@ static irqreturn_t axp20x_pek_irq(int irq, void *pwr)
   struct input_dev *idev = pwr;
   struct axp20x_pek *axp20x_pek = input_get_drvdata(idev);

 - if (irq == axp20x_pek-irq_dbr)
 + /*
 +  * The power-button is connected to ground so a falling edge (dbf)
 +  * means it is pressed.
 +  */
 + if (irq == axp20x_pek-irq_dbf)
   input_report_key(idev, KEY_POWER, true);
 - else if (irq == axp20x_pek-irq_dbf)
 + else if (irq == axp20x_pek-irq_dbr)
   input_report_key(idev, KEY_POWER, false);

   input_sync(idev);
 --
 2.4.3


 --
 Dmitry

 --
 You received this message because you are subscribed to the Google Groups 
 linux-sunxi group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to linux-sunxi+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC_v2 3/4] HID: hid-sony: Add IIO trigger support for SixAxis Controller

2015-06-23 Thread Simon Wood
---
 drivers/hid/hid-sony.c | 71 --
 1 file changed, 69 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index b7a7f0d..ce0526d 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -39,9 +39,11 @@
 #include linux/iio/iio.h
 #include linux/iio/sysfs.h
 #include linux/iio/buffer.h
+#include linux/iio/trigger.h
 #include linux/iio/trigger_consumer.h
 #include linux/iio/triggered_buffer.h
 #include linux/interrupt.h
+#include linux/irq_work.h
 
 #include hid-ids.h
 
@@ -855,9 +857,14 @@ enum sony_iio_axis {
AXIS_ACC_Z,
 };
 
+static void sony_iio_trigger_work(struct irq_work *work);
+
 struct sony_iio {
struct sony_sc *sc;
+   struct iio_trigger *trig;
+
u8 buff[16];/* 3x 16-bit + padding + timestamp */
+   struct irq_work work;
 #endif
 };
 
@@ -1076,6 +1083,13 @@ static int sony_raw_event(struct hid_device *hdev, 
struct hid_report *report,
sc-last_data[AXIS_ACC_X] = (rd[42]  8) + rd[41];
sc-last_data[AXIS_ACC_Y] = (rd[44]  8) + rd[43];
sc-last_data[AXIS_ACC_Z] = (rd[46]  8) + rd[45];
+
+   if (sc-indio_dev) {
+   struct sony_iio *data;
+
+   data = iio_priv(sc-indio_dev);
+   sony_iio_trigger_work(data-work);
+   }
 #endif
sixaxis_parse_report(sc, rd, size);
} else if (((sc-quirks  DUALSHOCK4_CONTROLLER_USB)  rd[0] == 0x01 
@@ -1869,6 +1883,28 @@ static const struct iio_info sony_iio_info = {
.driver_module = THIS_MODULE,
 };
 
+static void sony_iio_trigger_work(struct irq_work *work)
+{
+   struct sony_iio *data = container_of(work, struct sony_iio, work);
+
+   iio_trigger_poll(data-trig);
+}
+
+static ssize_t sony_iio_trigger_poll(struct device *dev,
+   struct device_attribute *attr, const char *buf, size_t count)
+{
+   struct iio_trigger *trig = to_iio_trigger(dev);
+   struct sony_iio *data = iio_trigger_get_drvdata(trig);
+
+   irq_work_queue(data-work);
+
+   return count;
+}
+
+static const struct iio_trigger_ops sony_iio_trigger_ops = {
+   .owner = THIS_MODULE,
+};
+
 static irqreturn_t sony_iio_trigger_handler(int irq, void *p)
 {
struct iio_poll_func *pf = p;
@@ -1910,11 +1946,29 @@ static int sony_iio_probe(struct sony_sc *sc)
indio_dev-channels = sony_sixaxis_channels;
indio_dev-num_channels = ARRAY_SIZE(sony_sixaxis_channels);
 
+   data-trig = iio_trigger_alloc(%s-dev%d, indio_dev-name,
+   indio_dev-id);
+   if (!data-trig) {
+   ret = -ENOMEM;
+   goto err;
+   }
+
+   data-trig-dev.parent = hdev-dev;
+   data-trig-ops = sony_iio_trigger_ops;
+   iio_trigger_set_drvdata(data-trig, indio_dev);
+   indio_dev-trig = iio_trigger_get(data-trig);
+
+   init_irq_work(data-work, sony_iio_trigger_work);
+
+   ret = iio_trigger_register(data-trig);
+   if (ret)
+   goto err_trigger_free;
+
ret = iio_triggered_buffer_setup(indio_dev, NULL,
sony_iio_trigger_handler, NULL);
if (ret  0) {
dev_err(hdev-dev, unable to setup iio triggered buffer\n);
-   goto err;
+   goto err_trigger_unregister;
}
 
ret = iio_device_register(indio_dev);
@@ -1926,6 +1980,11 @@ static int sony_iio_probe(struct sony_sc *sc)
 
 err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
+err_trigger_unregister:
+   if (data-trig)
+   iio_trigger_unregister(data-trig);
+err_trigger_free:
+   iio_trigger_free(data-trig);
 err:
kfree(indio_dev);
sc-indio_dev = NULL;
@@ -1934,11 +1993,19 @@ err:
 
 static void sony_iio_remove(struct sony_sc *sc)
 {
+   struct sony_iio *data;
+
if (!sc-indio_dev)
return;
 
-   iio_device_unregister(sc-indio_dev);
+   data = iio_priv(sc-indio_dev);
+
iio_triggered_buffer_cleanup(sc-indio_dev);
+   if (data-trig)
+   iio_trigger_unregister(data-trig);
+   iio_trigger_free(data-trig);
+   iio_device_unregister(sc-indio_dev);
+
kfree(sc-indio_dev);
sc-indio_dev = NULL;
 }
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC_v2 2/4] HID: hid-sony: Add IIO buffer support for SixAxis Controller

2015-06-23 Thread Simon Wood
---
 drivers/hid/hid-sony.c | 50 +++---
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index c4686e3..b7a7f0d 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -37,6 +37,11 @@
 #include linux/idr.h
 #include linux/input/mt.h
 #include linux/iio/iio.h
+#include linux/iio/sysfs.h
+#include linux/iio/buffer.h
+#include linux/iio/trigger_consumer.h
+#include linux/iio/triggered_buffer.h
+#include linux/interrupt.h
 
 #include hid-ids.h
 
@@ -852,6 +857,7 @@ enum sony_iio_axis {
 
 struct sony_iio {
struct sony_sc *sc;
+   u8 buff[16];/* 3x 16-bit + padding + timestamp */
 #endif
 };
 
@@ -861,6 +867,7 @@ static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 
*rdesc,
*rsize = sizeof(sixaxis_rdesc);
return sixaxis_rdesc;
 }
+
 static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
 unsigned int *rsize)
 {
@@ -1841,12 +1848,20 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev,
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
BIT(IIO_CHAN_INFO_OFFSET),  \
.address = AXIS_ACC_##_axis,\
+   .scan_index = AXIS_ACC_##_axis, \
+   .scan_type = {  \
+   .sign = 's',\
+   .realbits = 16, \
+   .storagebits = 16,  \
+   .shift = 0, \
+   },  \
 }
 
 static const struct iio_chan_spec sony_sixaxis_channels[] = {
SONY_ACC_CHANNEL(X),
SONY_ACC_CHANNEL(Y),
SONY_ACC_CHANNEL(Z),
+   IIO_CHAN_SOFT_TIMESTAMP(3),
 };
 
 static const struct iio_info sony_iio_info = {
@@ -1854,6 +1869,25 @@ static const struct iio_info sony_iio_info = {
.driver_module = THIS_MODULE,
 };
 
+static irqreturn_t sony_iio_trigger_handler(int irq, void *p)
+{
+   struct iio_poll_func *pf = p;
+   struct iio_dev *indio_dev = pf-indio_dev;
+   struct sony_iio *data = iio_priv(indio_dev);
+   int64_t time_ns = iio_get_time_ns();
+   int bit, i = 0;
+
+   for_each_set_bit(bit, indio_dev-active_scan_mask,
+indio_dev-masklength) {
+   ((u16 *)data-buff)[i++] = data-sc-last_data[bit];
+   }
+
+   iio_push_to_buffers_with_timestamp(indio_dev, data-buff, time_ns);
+   iio_trigger_notify_done(indio_dev-trig);
+
+   return IRQ_HANDLED;
+}
+
 static int sony_iio_probe(struct sony_sc *sc)
 {
struct hid_device *hdev = sc-hdev;
@@ -1871,18 +1905,27 @@ static int sony_iio_probe(struct sony_sc *sc)
 
indio_dev-dev.parent = hdev-dev;
indio_dev-name = dev_name(hdev-dev);
-   indio_dev-modes = INDIO_DIRECT_MODE;
+   indio_dev-modes = INDIO_DIRECT_MODE | INDIO_BUFFER_TRIGGERED;
indio_dev-info = sony_iio_info;
indio_dev-channels = sony_sixaxis_channels;
-   indio_dev-num_channels = 3;
+   indio_dev-num_channels = ARRAY_SIZE(sony_sixaxis_channels);
+
+   ret = iio_triggered_buffer_setup(indio_dev, NULL,
+   sony_iio_trigger_handler, NULL);
+   if (ret  0) {
+   dev_err(hdev-dev, unable to setup iio triggered buffer\n);
+   goto err;
+   }
 
ret = iio_device_register(indio_dev);
if (ret  0) {
hid_err(hdev, Unable to register iio device\n);
-   goto err;
+   goto err_buffer_cleanup;
}
return 0;
 
+err_buffer_cleanup:
+   iio_triggered_buffer_cleanup(indio_dev);
 err:
kfree(indio_dev);
sc-indio_dev = NULL;
@@ -1895,6 +1938,7 @@ static void sony_iio_remove(struct sony_sc *sc)
return;
 
iio_device_unregister(sc-indio_dev);
+   iio_triggered_buffer_cleanup(sc-indio_dev);
kfree(sc-indio_dev);
sc-indio_dev = NULL;
 }
-- 
2.1.4

--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC_v2 0/4] HID: hid-sony: Add IIO Suport for Motion Controllers

2015-06-23 Thread Simon Wood

This series of patches is a RFC for the idea of connecting motion capability
controllers to the IIO subsystem, initially targeting the Sony SixAxis
controller. In the future I hope that this can be used for sensor packs used
in VR headset/devices.

The advantage of the IIO subsystem is that the data is presented in SI units,
although it is noted that the current API requires root level access - this is
really a distribution requirement (UDEV rules can make '/dev/iiodevice0'
accessible).

The RFC is in 4 parts, split into logical steps:
[PATCH 1/4] HID: hid-sony: Add basic IIO support for SixAxis Controller
[PATCH 2/4] HID: hid-sony: Add IIO buffer support for SixAxis Controller
[PATCH 3/4] HID: hid-sony: Add IIO trigger support for SixAxis Controller
[PATCH 4/4] HID: hid-sony: Add IIO support for DualShock4 Controller

The SixAxis contains accelerometers, the DS4 contains accelerometers and gyros.

The next stage would be support the PS Move controller, which contains
accelerometers, gyros and magnetometers.

As an example of IIO usage I would point to RTIMULib, which recently showed
a full 9-dof IMU fusion via IIO. (1)


Known Bug:
At present the 3rd patch introduces the issue that once loaded and a device
connects, the module can not be unloaded (even after device disconnects).

It seems that the refcount is being increased, but not decreased.
--
$ cat /sys/module/hid_sony/refcnt 
2
--


(1) 
https://richardstechnotes.wordpress.com/2015/06/17/rteiioimu-driving-a-9-dof-imu-via-industrial-io-iio/
--
To unsubscribe from this list: send the line unsubscribe linux-input in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC_v2 4/4] HID: hid-sony: Add IIO support for DualShock4 Controller

2015-06-23 Thread Simon Wood
---
 drivers/hid/hid-sony.c | 87 +-
 1 file changed, 79 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index ce0526d..f1c1a16 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -62,7 +62,7 @@
DUALSHOCK4_CONTROLLER)
 #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
 #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
-#define SONY_IIO_SUPPORT SIXAXIS_CONTROLLER
+#define SONY_IIO_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
 
 #define MAX_LEDS 4
 
@@ -848,13 +848,16 @@ struct sony_sc {
 #if IS_BUILTIN(CONFIG_IIO) || \
(IS_MODULE(CONFIG_IIO)  IS_MODULE(CONFIG_HID_SONY))
struct iio_dev *indio_dev;
-   __u16 last_data[3];
+   __s16 last_data[6];
 };
 
 enum sony_iio_axis {
AXIS_ACC_X,
AXIS_ACC_Y,
AXIS_ACC_Z,
+   AXIS_GYRO_X,
+   AXIS_GYRO_Y,
+   AXIS_GYRO_Z,
 };
 
 static void sony_iio_trigger_work(struct irq_work *work);
@@ -863,7 +866,7 @@ struct sony_iio {
struct sony_sc *sc;
struct iio_trigger *trig;
 
-   u8 buff[16];/* 3x 16-bit + padding + timestamp */
+   u8 buff[24];/* 6x 16-bit + padding + timestamp */
struct irq_work work;
 #endif
 };
@@ -1095,6 +1098,25 @@ static int sony_raw_event(struct hid_device *hdev, 
struct hid_report *report,
} else if (((sc-quirks  DUALSHOCK4_CONTROLLER_USB)  rd[0] == 0x01 
size == 64) || ((sc-quirks  DUALSHOCK4_CONTROLLER_BT)
 rd[0] == 0x11  size == 78)) {
+#if IS_BUILTIN(CONFIG_IIO) || \
+   (IS_MODULE(CONFIG_IIO)  IS_MODULE(CONFIG_HID_SONY))
+   int offset = (sc-quirks  DUALSHOCK4_CONTROLLER_USB) ? 13 : 15;
+
+   sc-last_data[AXIS_ACC_X] = (rd[offset+7]  8) + rd[offset+6];
+   sc-last_data[AXIS_ACC_Y] = (rd[offset+9]  8) + rd[offset+8];
+   sc-last_data[AXIS_ACC_Z] = (rd[offset+11]  8) + 
rd[offset+10];
+
+   sc-last_data[AXIS_GYRO_X] = (rd[offset+1]  8) + rd[offset];
+   sc-last_data[AXIS_GYRO_Y] = (rd[offset+3]  8) + rd[offset+2];
+   sc-last_data[AXIS_GYRO_Z] = (rd[offset+5]  8) + rd[offset+4];
+
+   if (sc-indio_dev) {
+   struct sony_iio *data;
+
+   data = iio_priv(sc-indio_dev);
+   sony_iio_trigger_work(data-work);
+   }
+#endif
dualshock4_parse_report(sc, rd, size);
}
 
@@ -1827,6 +1849,7 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_RAW:
switch (chan-type) {
case IIO_ACCEL:
+   case IIO_ANGL_VEL:
*val = data-sc-last_data[chan-address];
return IIO_VAL_INT;
default:
@@ -1835,8 +1858,17 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_SCALE:
switch (chan-type) {
case IIO_ACCEL:
-   *val = 0;   /* 9.80665/117 = 0.084540086 */
-   *val2 = 84540;
+   if (data-sc-quirks  SIXAXIS_CONTROLLER) {
+   *val = 0;   /* 9.80665/117 = 0.084540086 */
+   *val2 = 84540;
+   } else if (data-sc-quirks  DUALSHOCK4_CONTROLLER) {
+   *val = 0;   /* 9.80665/8192 = 0.001197101 */
+   *val2 = 1197;
+   }
+   return IIO_VAL_INT_PLUS_MICRO;
+   case IIO_ANGL_VEL:
+   *val = 0;   /* 0.001 */
+   *val2 = 1000;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
@@ -1844,7 +1876,13 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev,
case IIO_CHAN_INFO_OFFSET:
switch (chan-type) {
case IIO_ACCEL:
-   *val = -512;
+   if (data-sc-quirks  SIXAXIS_CONTROLLER)
+   *val = -512;
+   else if (data-sc-quirks  DUALSHOCK4_CONTROLLER)
+   *val = 0;
+   return IIO_VAL_INT;
+   case IIO_ANGL_VEL:
+   *val = 0;
return IIO_VAL_INT;
default:
return -EINVAL;
@@ -1871,6 +1909,23 @@ static int sony_iio_read_raw(struct iio_dev *indio_dev,
},  \
 }
 
+#define SONY_GYRO_CHANNEL(_axis) {  \
+   .type = IIO_ANGL_VEL,   \
+   .modified = 1, 

[RFC_v2 1/4] HID: hid-sony: Add basic IIO support for SixAxis Controller

2015-06-23 Thread Simon Wood
---
 drivers/hid/hid-sony.c | 153 -
 1 file changed, 152 insertions(+), 1 deletion(-)

diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 6ca96ce..c4686e3 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -36,6 +36,7 @@
 #include linux/list.h
 #include linux/idr.h
 #include linux/input/mt.h
+#include linux/iio/iio.h
 
 #include hid-ids.h
 
@@ -54,6 +55,7 @@
DUALSHOCK4_CONTROLLER)
 #define SONY_BATTERY_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
 #define SONY_FF_SUPPORT (SIXAXIS_CONTROLLER | DUALSHOCK4_CONTROLLER)
+#define SONY_IIO_SUPPORT SIXAXIS_CONTROLLER
 
 #define MAX_LEDS 4
 
@@ -835,6 +837,22 @@ struct sony_sc {
__u8 led_delay_on[MAX_LEDS];
__u8 led_delay_off[MAX_LEDS];
__u8 led_count;
+
+#if IS_BUILTIN(CONFIG_IIO) || \
+   (IS_MODULE(CONFIG_IIO)  IS_MODULE(CONFIG_HID_SONY))
+   struct iio_dev *indio_dev;
+   __u16 last_data[3];
+};
+
+enum sony_iio_axis {
+   AXIS_ACC_X,
+   AXIS_ACC_Y,
+   AXIS_ACC_Z,
+};
+
+struct sony_iio {
+   struct sony_sc *sc;
+#endif
 };
 
 static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -843,7 +861,6 @@ static __u8 *sixaxis_fixup(struct hid_device *hdev, __u8 
*rdesc,
*rsize = sizeof(sixaxis_rdesc);
return sixaxis_rdesc;
 }
-
 static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
 unsigned int *rsize)
 {
@@ -1047,6 +1064,12 @@ static int sony_raw_event(struct hid_device *hdev, 
struct hid_report *report,
swap(rd[45], rd[46]);
swap(rd[47], rd[48]);
 
+#if IS_BUILTIN(CONFIG_IIO) || \
+   (IS_MODULE(CONFIG_IIO)  IS_MODULE(CONFIG_HID_SONY))
+   sc-last_data[AXIS_ACC_X] = (rd[42]  8) + rd[41];
+   sc-last_data[AXIS_ACC_Y] = (rd[44]  8) + rd[43];
+   sc-last_data[AXIS_ACC_Z] = (rd[46]  8) + rd[45];
+#endif
sixaxis_parse_report(sc, rd, size);
} else if (((sc-quirks  DUALSHOCK4_CONTROLLER_USB)  rd[0] == 0x01 
size == 64) || ((sc-quirks  DUALSHOCK4_CONTROLLER_BT)
@@ -1769,6 +1792,114 @@ static void sony_battery_remove(struct sony_sc *sc)
sc-battery_desc.name = NULL;
 }
 
+#if IS_BUILTIN(CONFIG_IIO) || \
+   (IS_MODULE(CONFIG_IIO)  IS_MODULE(CONFIG_HID_SONY))
+
+static int sony_iio_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val, int *val2,
+ long mask)
+{
+   struct sony_iio *data = iio_priv(indio_dev);
+
+   switch (mask) {
+   case IIO_CHAN_INFO_RAW:
+   switch (chan-type) {
+   case IIO_ACCEL:
+   *val = data-sc-last_data[chan-address];
+   return IIO_VAL_INT;
+   default:
+   return -EINVAL;
+   }
+   case IIO_CHAN_INFO_SCALE:
+   switch (chan-type) {
+   case IIO_ACCEL:
+   *val = 0;   /* 9.80665/117 = 0.084540086 */
+   *val2 = 84540;
+   return IIO_VAL_INT_PLUS_MICRO;
+   default:
+   return -EINVAL;
+   }
+   case IIO_CHAN_INFO_OFFSET:
+   switch (chan-type) {
+   case IIO_ACCEL:
+   *val = -512;
+   return IIO_VAL_INT;
+   default:
+   return -EINVAL;
+   }
+   }
+
+   return -EINVAL;
+}
+
+#define SONY_ACC_CHANNEL(_axis) {   \
+   .type = IIO_ACCEL,  \
+   .modified = 1,  \
+   .channel2 = IIO_MOD_##_axis,\
+   .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
+   .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |  \
+   BIT(IIO_CHAN_INFO_OFFSET),  \
+   .address = AXIS_ACC_##_axis,\
+}
+
+static const struct iio_chan_spec sony_sixaxis_channels[] = {
+   SONY_ACC_CHANNEL(X),
+   SONY_ACC_CHANNEL(Y),
+   SONY_ACC_CHANNEL(Z),
+};
+
+static const struct iio_info sony_iio_info = {
+   .read_raw = sony_iio_read_raw,
+   .driver_module = THIS_MODULE,
+};
+
+static int sony_iio_probe(struct sony_sc *sc)
+{
+   struct hid_device *hdev = sc-hdev;
+   struct iio_dev *indio_dev;
+   struct sony_iio *data;
+   int ret;
+
+   indio_dev = iio_device_alloc(sizeof(*data));
+   if (!indio_dev)
+   return -ENOMEM;
+
+   sc-indio_dev = indio_dev;
+   data = iio_priv(indio_dev);
+   data-sc = sc;
+
+   indio_dev-dev.parent = hdev-dev;
+   indio_dev-name =