Re: [PATCH] touchscreen: sun4i-ts: Really fix A10 temperature reporting
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
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
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
-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
-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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
--- 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
--- 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
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
--- 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
--- 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 =