Commit 72c0870e authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input

Pull input updates from Dmitry Torokhov:

 - updates to Ilitech driver to support ILI2117

 - face lift of st1232 driver to support MT-B protocol

 - a new driver for i.MX system controller keys

 - mpr121 driver now supports polling mode

 - various input drivers have been switched away from input_polled_dev
   to use polled mode of regular input devices

 - other assorted cleanups and fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (70 commits)
  Input: synaptics-rmi4 - fix various V4L2 compliance problems in F54
  Input: synaptics - switch another X1 Carbon 6 to RMI/SMbus
  Input: fix Kconfig indentation
  Input: imx_sc_key - correct SCU message structure to avoid stack corruption
  Input: ili210x - optionally show calibrate sysfs attribute
  Input: ili210x - add resolution to chip operations structure
  Input: ili210x - do not retrieve/print chip firmware version
  Input: mms114 - use device_get_match_data
  Input: ili210x - remove unneeded suspend and resume handlers
  Input: ili210x - do not unconditionally mark touchscreen as wakeup source
  Input: ili210x - define and use chip operations structure
  Input: ili210x - do not set parent device explicitly
  Input: ili210x - handle errors from input_mt_init_slots()
  Input: ili210x - switch to using threaded IRQ
  Input: ili210x - add ILI2117 support
  dt-bindings: input: touchscreen: ad7879: generic node names in example
  Input: ar1021 - fix typo in preprocessor macro name
  Input: synaptics-rmi4 - simplify data read in rmi_f54_work
  Input: kxtj9 - switch to using polled mode of input devices
  Input: kxtj9 - switch to using managed resources
  ...
parents d10032dd 976e3645
...@@ -157,6 +157,15 @@ Required properties: ...@@ -157,6 +157,15 @@ Required properties:
Optional properties: Optional properties:
- timeout-sec: contains the watchdog timeout in seconds. - timeout-sec: contains the watchdog timeout in seconds.
SCU key bindings based on SCU Message Protocol
------------------------------------------------------------
Required properties:
- compatible: should be:
"fsl,imx8qxp-sc-key"
followed by "fsl,imx-sc-key";
- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt
Example (imx8qxp): Example (imx8qxp):
------------- -------------
aliases { aliases {
...@@ -220,6 +229,11 @@ firmware { ...@@ -220,6 +229,11 @@ firmware {
compatible = "fsl,imx8qxp-sc-rtc"; compatible = "fsl,imx8qxp-sc-rtc";
}; };
scu_key: scu-key {
compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
linux,keycodes = <KEY_POWER>;
};
watchdog { watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt"; compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
timeout-sec = <60>; timeout-sec = <60>;
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/fsl,mpr121-touchkey.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Freescale MPR121 capacitive touch sensor controller
maintainers:
- Dmitry Torokhov <dmitry.torokhov@gmail.com>
description: |
The MPR121 supports up to 12 completely independent electrodes/capacitance
sensing inputs in which 8 are multifunctional for LED driving and GPIO.
https://www.nxp.com/docs/en/data-sheet/MPR121.pdf
allOf:
- $ref: input.yaml#
anyOf:
- required: [ interrupts ]
- required: [ poll-interval ]
properties:
compatible:
const: fsl,mpr121-touchkey
reg:
maxItems: 1
interrupts:
maxItems: 1
vdd-supply:
maxItems: 1
linux,keycodes:
minItems: 1
maxItems: 12
wakeup-source:
description: Use any event on keypad as wakeup event.
type: boolean
required:
- compatible
- reg
- vdd-supply
- linux,keycodes
examples:
- |
// Example with interrupts
#include "dt-bindings/input/input.h"
i2c {
#address-cells = <1>;
#size-cells = <0>;
mpr121@5a {
compatible = "fsl,mpr121-touchkey";
reg = <0x5a>;
interrupt-parent = <&gpio1>;
interrupts = <28 2>;
autorepeat;
vdd-supply = <&ldo4_reg>;
linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>,
<KEY_4>, <KEY_5>, <KEY_6>, <KEY_7>,
<KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>;
};
};
- |
// Example with polling
#include "dt-bindings/input/input.h"
i2c {
#address-cells = <1>;
#size-cells = <0>;
mpr121@5a {
compatible = "fsl,mpr121-touchkey";
reg = <0x5a>;
poll-interval = <20>;
autorepeat;
vdd-supply = <&ldo4_reg>;
linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>,
<KEY_4>, <KEY_5>, <KEY_6>, <KEY_7>,
<KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>;
};
};
Ilitek ILI210x/ILI251x touchscreen controller Ilitek ILI210x/ILI2117/ILI251x touchscreen controller
Required properties: Required properties:
- compatible: - compatible:
ilitek,ili210x for ILI210x ilitek,ili210x for ILI210x
ilitek,ili2117 for ILI2117
ilitek,ili251x for ILI251x ilitek,ili251x for ILI251x
- reg: The I2C address of the device - reg: The I2C address of the device
......
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/input.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Common input schema binding
maintainers:
- Dmitry Torokhov <dmitry.torokhov@gmail.com>
properties:
autorepeat:
description: Enable autorepeat when key is pressed and held down.
type: boolean
linux,keycodes:
description:
Specifies an array of numeric keycode values to be used for reporting
button presses.
allOf:
- $ref: /schemas/types.yaml#/definitions/uint32-array
- items:
minimum: 0
maximum: 0xff
poll-interval:
description: Poll interval time in milliseconds.
$ref: /schemas/types.yaml#/definitions/uint32
power-off-time-sec:
description:
Duration in seconds which the key should be kept pressed for device to
power off automatically. Device with key pressed shutdown feature can
specify this property.
$ref: /schemas/types.yaml#/definitions/uint32
General Keys Properties:
Optional properties for Keys:
- power-off-time-sec: Duration in seconds which the key should be kept
pressed for device to power off automatically. Device with key pressed
shutdown feature can specify this property.
- linux,keycodes: Specifies the numeric keycode values to be used for
reporting key presses.
* Freescale MPR121 Controllor
Required Properties:
- compatible: Should be "fsl,mpr121-touchkey"
- reg: The I2C slave address of the device.
- interrupts: The interrupt number to the cpu.
- vdd-supply: Phandle to the Vdd power supply.
- linux,keycodes: Specifies an array of numeric keycode values to
be used for reporting button presses. The array can
contain up to 12 entries.
Optional Properties:
- wakeup-source: Use any event on keypad as wakeup event.
- autorepeat: Enable autorepeat feature.
Example:
#include "dt-bindings/input/input.h"
touchkey: mpr121@5a {
compatible = "fsl,mpr121-touchkey";
reg = <0x5a>;
interrupt-parent = <&gpio1>;
interrupts = <28 2>;
autorepeat;
vdd-supply = <&ldo4_reg>;
linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>,
<KEY_4> <KEY_5>, <KEY_6>, <KEY_7>,
<KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>;
};
...@@ -10,13 +10,13 @@ Documentation/devicetree/bindings/mfd/mt6397.txt ...@@ -10,13 +10,13 @@ Documentation/devicetree/bindings/mfd/mt6397.txt
Required properties: Required properties:
- compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys" - compatible: "mediatek,mt6397-keys" or "mediatek,mt6323-keys"
- linux,keycodes: See Documentation/devicetree/bindings/input/keys.txt - linux,keycodes: See Documentation/devicetree/bindings/input/input.yaml
Optional Properties: Optional Properties:
- wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt - wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt
- mediatek,long-press-mode: Long press key shutdown setting, 1 for - mediatek,long-press-mode: Long press key shutdown setting, 1 for
pwrkey only, 2 for pwrkey/homekey together, others for disabled. pwrkey only, 2 for pwrkey/homekey together, others for disabled.
- power-off-time-sec: See Documentation/devicetree/bindings/input/keys.txt - power-off-time-sec: See Documentation/devicetree/bindings/input/input.yaml
Example: Example:
......
...@@ -15,7 +15,7 @@ Optional properties: ...@@ -15,7 +15,7 @@ Optional properties:
- st,onkey-pu-inactive: onkey pull up is not active - st,onkey-pu-inactive: onkey pull up is not active
- power-off-time-sec: Duration in seconds which the key should be kept - power-off-time-sec: Duration in seconds which the key should be kept
pressed for device to power off automatically (from 1 to 16 seconds). pressed for device to power off automatically (from 1 to 16 seconds).
see See Documentation/devicetree/bindings/input/keys.txt see See Documentation/devicetree/bindings/input/input.yaml
Example: Example:
......
...@@ -38,7 +38,7 @@ Optional properties: ...@@ -38,7 +38,7 @@ Optional properties:
Example: Example:
ad7879@2c { touchscreen0@2c {
compatible = "adi,ad7879-1"; compatible = "adi,ad7879-1";
reg = <0x2c>; reg = <0x2c>;
interrupt-parent = <&gpio1>; interrupt-parent = <&gpio1>;
...@@ -52,7 +52,7 @@ Example: ...@@ -52,7 +52,7 @@ Example:
adi,conversion-interval = /bits/ 8 <255>; adi,conversion-interval = /bits/ 8 <255>;
}; };
ad7879@1 { touchscreen1@1 {
compatible = "adi,ad7879"; compatible = "adi,ad7879";
spi-max-frequency = <5000000>; spi-max-frequency = <5000000>;
reg = <1>; reg = <1>;
......
...@@ -30,6 +30,7 @@ Required properties: ...@@ -30,6 +30,7 @@ Required properties:
Optional properties: Optional properties:
- reset-gpios: GPIO specification for the RESET input - reset-gpios: GPIO specification for the RESET input
- wake-gpios: GPIO specification for the WAKE input - wake-gpios: GPIO specification for the WAKE input
- vcc-supply: Regulator that supplies the touchscreen
- pinctrl-names: should be "default" - pinctrl-names: should be "default"
- pinctrl-0: a phandle pointing to the pin settings for the - pinctrl-0: a phandle pointing to the pin settings for the
......
...@@ -123,6 +123,15 @@ void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval) ...@@ -123,6 +123,15 @@ void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval)
} }
EXPORT_SYMBOL(input_set_max_poll_interval); EXPORT_SYMBOL(input_set_max_poll_interval);
int input_get_poll_interval(struct input_dev *dev)
{
if (!dev->poller)
return -EINVAL;
return dev->poller->poll_interval;
}
EXPORT_SYMBOL(input_get_poll_interval);
/* SYSFS interface */ /* SYSFS interface */
static ssize_t input_dev_get_poll_interval(struct device *dev, static ssize_t input_dev_get_poll_interval(struct device *dev,
......
...@@ -334,7 +334,6 @@ config JOYSTICK_MAPLE ...@@ -334,7 +334,6 @@ config JOYSTICK_MAPLE
config JOYSTICK_PSXPAD_SPI config JOYSTICK_PSXPAD_SPI
tristate "PlayStation 1/2 joypads via SPI interface" tristate "PlayStation 1/2 joypads via SPI interface"
depends on SPI depends on SPI
select INPUT_POLLDEV
help help
Say Y here if you wish to connect PlayStation 1/2 joypads Say Y here if you wish to connect PlayStation 1/2 joypads
via SPI interface. via SPI interface.
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -60,7 +59,7 @@ static const u8 PSX_CMD_ENABLE_MOTOR[] = { ...@@ -60,7 +59,7 @@ static const u8 PSX_CMD_ENABLE_MOTOR[] = {
struct psxpad { struct psxpad {
struct spi_device *spi; struct spi_device *spi;
struct input_polled_dev *pdev; struct input_dev *idev;
char phys[0x20]; char phys[0x20];
bool motor1enable; bool motor1enable;
bool motor2enable; bool motor2enable;
...@@ -140,8 +139,7 @@ static void psxpad_set_motor_level(struct psxpad *pad, ...@@ -140,8 +139,7 @@ static void psxpad_set_motor_level(struct psxpad *pad,
static int psxpad_spi_play_effect(struct input_dev *idev, static int psxpad_spi_play_effect(struct input_dev *idev,
void *data, struct ff_effect *effect) void *data, struct ff_effect *effect)
{ {
struct input_polled_dev *pdev = input_get_drvdata(idev); struct psxpad *pad = input_get_drvdata(idev);
struct psxpad *pad = pdev->private;
switch (effect->type) { switch (effect->type) {
case FF_RUMBLE: case FF_RUMBLE:
...@@ -158,10 +156,9 @@ static int psxpad_spi_init_ff(struct psxpad *pad) ...@@ -158,10 +156,9 @@ static int psxpad_spi_init_ff(struct psxpad *pad)
{ {
int err; int err;
input_set_capability(pad->pdev->input, EV_FF, FF_RUMBLE); input_set_capability(pad->idev, EV_FF, FF_RUMBLE);
err = input_ff_create_memless(pad->pdev->input, NULL, err = input_ff_create_memless(pad->idev, NULL, psxpad_spi_play_effect);
psxpad_spi_play_effect);
if (err) { if (err) {
dev_err(&pad->spi->dev, dev_err(&pad->spi->dev,
"input_ff_create_memless() failed: %d\n", err); "input_ff_create_memless() failed: %d\n", err);
...@@ -189,24 +186,25 @@ static inline int psxpad_spi_init_ff(struct psxpad *pad) ...@@ -189,24 +186,25 @@ static inline int psxpad_spi_init_ff(struct psxpad *pad)
} }
#endif /* CONFIG_JOYSTICK_PSXPAD_SPI_FF */ #endif /* CONFIG_JOYSTICK_PSXPAD_SPI_FF */
static void psxpad_spi_poll_open(struct input_polled_dev *pdev) static int psxpad_spi_poll_open(struct input_dev *input)
{ {
struct psxpad *pad = pdev->private; struct psxpad *pad = input_get_drvdata(input);
pm_runtime_get_sync(&pad->spi->dev); pm_runtime_get_sync(&pad->spi->dev);
return 0;
} }
static void psxpad_spi_poll_close(struct input_polled_dev *pdev) static void psxpad_spi_poll_close(struct input_dev *input)
{ {
struct psxpad *pad = pdev->private; struct psxpad *pad = input_get_drvdata(input);
pm_runtime_put_sync(&pad->spi->dev); pm_runtime_put_sync(&pad->spi->dev);
} }
static void psxpad_spi_poll(struct input_polled_dev *pdev) static void psxpad_spi_poll(struct input_dev *input)
{ {
struct psxpad *pad = pdev->private; struct psxpad *pad = input_get_drvdata(input);
struct input_dev *input = pdev->input;
u8 b_rsp3, b_rsp4; u8 b_rsp3, b_rsp4;
int err; int err;
...@@ -284,7 +282,6 @@ static void psxpad_spi_poll(struct input_polled_dev *pdev) ...@@ -284,7 +282,6 @@ static void psxpad_spi_poll(struct input_polled_dev *pdev)
static int psxpad_spi_probe(struct spi_device *spi) static int psxpad_spi_probe(struct spi_device *spi)
{ {
struct psxpad *pad; struct psxpad *pad;
struct input_polled_dev *pdev;
struct input_dev *idev; struct input_dev *idev;
int err; int err;
...@@ -292,31 +289,26 @@ static int psxpad_spi_probe(struct spi_device *spi) ...@@ -292,31 +289,26 @@ static int psxpad_spi_probe(struct spi_device *spi)
if (!pad) if (!pad)
return -ENOMEM; return -ENOMEM;
pdev = input_allocate_polled_device(); idev = devm_input_allocate_device(&spi->dev);
if (!pdev) { if (!idev) {
dev_err(&spi->dev, "failed to allocate input device\n"); dev_err(&spi->dev, "failed to allocate input device\n");
return -ENOMEM; return -ENOMEM;
} }
/* input poll device settings */ /* input poll device settings */
pad->pdev = pdev; pad->idev = idev;
pad->spi = spi; pad->spi = spi;
pdev->private = pad;
pdev->open = psxpad_spi_poll_open;
pdev->close = psxpad_spi_poll_close;
pdev->poll = psxpad_spi_poll;
/* poll interval is about 60fps */
pdev->poll_interval = 16;
pdev->poll_interval_min = 8;
pdev->poll_interval_max = 32;
/* input device settings */ /* input device settings */
idev = pdev->input; input_set_drvdata(idev, pad);
idev->name = "PlayStation 1/2 joypad"; idev->name = "PlayStation 1/2 joypad";
snprintf(pad->phys, sizeof(pad->phys), "%s/input", dev_name(&spi->dev)); snprintf(pad->phys, sizeof(pad->phys), "%s/input", dev_name(&spi->dev));
idev->id.bustype = BUS_SPI; idev->id.bustype = BUS_SPI;
idev->open = psxpad_spi_poll_open;
idev->close = psxpad_spi_poll_close;
/* key/value map settings */ /* key/value map settings */
input_set_abs_params(idev, ABS_X, 0, 255, 0, 0); input_set_abs_params(idev, ABS_X, 0, 255, 0, 0);
input_set_abs_params(idev, ABS_Y, 0, 255, 0, 0); input_set_abs_params(idev, ABS_Y, 0, 255, 0, 0);
...@@ -354,11 +346,23 @@ static int psxpad_spi_probe(struct spi_device *spi) ...@@ -354,11 +346,23 @@ static int psxpad_spi_probe(struct spi_device *spi)
/* pad settings */ /* pad settings */
psxpad_set_motor_level(pad, 0, 0); psxpad_set_motor_level(pad, 0, 0);
err = input_setup_polling(idev, psxpad_spi_poll);
if (err) {
dev_err(&spi->dev, "failed to set up polling: %d\n", err);
return err;
}
/* poll interval is about 60fps */
input_set_poll_interval(idev, 16);
input_set_min_poll_interval(idev, 8);
input_set_max_poll_interval(idev, 32);
/* register input poll device */ /* register input poll device */
err = input_register_polled_device(pdev); err = input_register_device(idev);
if (err) { if (err) {
dev_err(&spi->dev, dev_err(&spi->dev,
"failed to register input poll device: %d\n", err); "failed to register input device: %d\n", err);
return err; return err;
} }
......
...@@ -16,7 +16,6 @@ if INPUT_KEYBOARD ...@@ -16,7 +16,6 @@ if INPUT_KEYBOARD
config KEYBOARD_ADC config KEYBOARD_ADC
tristate "ADC Ladder Buttons" tristate "ADC Ladder Buttons"
depends on IIO depends on IIO
select INPUT_POLLDEV
help help
This driver implements support for buttons connected This driver implements support for buttons connected
to an ADC using a resistor ladder. to an ADC using a resistor ladder.
...@@ -168,14 +167,14 @@ config KEYBOARD_QT1050 ...@@ -168,14 +167,14 @@ config KEYBOARD_QT1050
the module will be called qt1050 the module will be called qt1050
config KEYBOARD_QT1070 config KEYBOARD_QT1070
tristate "Atmel AT42QT1070 Touch Sensor Chip" tristate "Atmel AT42QT1070 Touch Sensor Chip"
depends on I2C depends on I2C
help help
Say Y here if you want to use Atmel AT42QT1070 QTouch Say Y here if you want to use Atmel AT42QT1070 QTouch
Sensor chip as input device. Sensor chip as input device.
To compile this driver as a module, choose M here: To compile this driver as a module, choose M here:
the module will be called qt1070 the module will be called qt1070
config KEYBOARD_QT2160 config KEYBOARD_QT2160
tristate "Atmel AT42QT2160 Touch Sensor Chip" tristate "Atmel AT42QT2160 Touch Sensor Chip"
...@@ -191,7 +190,6 @@ config KEYBOARD_CLPS711X ...@@ -191,7 +190,6 @@ config KEYBOARD_CLPS711X
tristate "CLPS711X Keypad support" tristate "CLPS711X Keypad support"
depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST) depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST)
select INPUT_MATRIXKMAP select INPUT_MATRIXKMAP
select INPUT_POLLDEV
help help
Say Y here to enable the matrix keypad on the Cirrus Logic Say Y here to enable the matrix keypad on the Cirrus Logic
CLPS711X CPUs. CLPS711X CPUs.
...@@ -250,7 +248,6 @@ config KEYBOARD_GPIO ...@@ -250,7 +248,6 @@ config KEYBOARD_GPIO
config KEYBOARD_GPIO_POLLED config KEYBOARD_GPIO_POLLED
tristate "Polled GPIO buttons" tristate "Polled GPIO buttons"
depends on GPIOLIB depends on GPIOLIB
select INPUT_POLLDEV
help help
This driver implements support for buttons connected This driver implements support for buttons connected
to GPIO pins that are not capable of generating interrupts. to GPIO pins that are not capable of generating interrupts.
...@@ -342,7 +339,6 @@ config KEYBOARD_HIL ...@@ -342,7 +339,6 @@ config KEYBOARD_HIL
config KEYBOARD_HP6XX config KEYBOARD_HP6XX
tristate "HP Jornada 6xx keyboard" tristate "HP Jornada 6xx keyboard"
depends on SH_HP6XX depends on SH_HP6XX
select INPUT_POLLDEV
help help
Say Y here if you have a HP Jornada 620/660/680/690 and want to Say Y here if you have a HP Jornada 620/660/680/690 and want to
support the built-in keyboard. support the built-in keyboard.
...@@ -469,6 +465,16 @@ config KEYBOARD_IMX ...@@ -469,6 +465,16 @@ config KEYBOARD_IMX
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called imx_keypad. module will be called imx_keypad.
config KEYBOARD_IMX_SC_KEY
tristate "IMX SCU Key Driver"
depends on IMX_SCU
help
This is the system controller key driver for NXP i.MX SoCs with
system controller inside.
To compile this driver as a module, choose M here: the
module will be called imx_sc_key.
config KEYBOARD_NEWTON config KEYBOARD_NEWTON
tristate "Newton keyboard" tristate "Newton keyboard"
select SERIO select SERIO
......
...@@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o ...@@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.o
obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o obj-$(CONFIG_KEYBOARD_IMX) += imx_keypad.o
obj-$(CONFIG_KEYBOARD_IMX_SC_KEY) += imx_sc_key.o
obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o obj-$(CONFIG_KEYBOARD_HP6XX) += jornada680_kbd.o
obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o obj-$(CONFIG_KEYBOARD_HP7XX) += jornada720_kbd.o
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <linux/iio/consumer.h> #include <linux/iio/consumer.h>
#include <linux/iio/types.h> #include <linux/iio/types.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -30,9 +29,9 @@ struct adc_keys_state { ...@@ -30,9 +29,9 @@ struct adc_keys_state {
const struct adc_keys_button *map; const struct adc_keys_button *map;
}; };
static void adc_keys_poll(struct input_polled_dev *dev) static void adc_keys_poll(struct input_dev *input)
{ {
struct adc_keys_state *st = dev->private; struct adc_keys_state *st = input_get_drvdata(input);
int i, value, ret; int i, value, ret;
u32 diff, closest = 0xffffffff; u32 diff, closest = 0xffffffff;
int keycode = 0; int keycode = 0;
...@@ -55,12 +54,12 @@ static void adc_keys_poll(struct input_polled_dev *dev) ...@@ -55,12 +54,12 @@ static void adc_keys_poll(struct input_polled_dev *dev)
keycode = 0; keycode = 0;
if (st->last_key && st->last_key != keycode) if (st->last_key && st->last_key != keycode)
input_report_key(dev->input, st->last_key, 0); input_report_key(input, st->last_key, 0);
if (keycode) if (keycode)
input_report_key(dev->input, keycode, 1); input_report_key(input, keycode, 1);
input_sync(dev->input); input_sync(input);
st->last_key = keycode; st->last_key = keycode;
} }
...@@ -108,7 +107,6 @@ static int adc_keys_probe(struct platform_device *pdev) ...@@ -108,7 +107,6 @@ static int adc_keys_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct adc_keys_state *st; struct adc_keys_state *st;
struct input_polled_dev *poll_dev;
struct input_dev *input; struct input_dev *input;
enum iio_chan_type type; enum iio_chan_type type;
int i, value; int i, value;
...@@ -145,19 +143,13 @@ static int adc_keys_probe(struct platform_device *pdev) ...@@ -145,19 +143,13 @@ static int adc_keys_probe(struct platform_device *pdev)
if (error) if (error)
return error; return error;
poll_dev = devm_input_allocate_polled_device(dev); input = devm_input_allocate_device(dev);
if (!poll_dev) { if (!input) {
dev_err(dev, "failed to allocate input device\n"); dev_err(dev, "failed to allocate input device\n");
return -ENOMEM; return -ENOMEM;
} }
if (!device_property_read_u32(dev, "poll-interval", &value)) input_set_drvdata(input, st);
poll_dev->poll_interval = value;
poll_dev->poll = adc_keys_poll;
poll_dev->private = st;
input = poll_dev->input;
input->name = pdev->name; input->name = pdev->name;
input->phys = "adc-keys/input0"; input->phys = "adc-keys/input0";
...@@ -174,7 +166,17 @@ static int adc_keys_probe(struct platform_device *pdev) ...@@ -174,7 +166,17 @@ static int adc_keys_probe(struct platform_device *pdev)
if (device_property_read_bool(dev, "autorepeat")) if (device_property_read_bool(dev, "autorepeat"))
__set_bit(EV_REP, input->evbit); __set_bit(EV_REP, input->evbit);
error = input_register_polled_device(poll_dev);
error = input_setup_polling(input, adc_keys_poll);
if (error) {
dev_err(dev, "Unable to set up polling: %d\n", error);
return error;
}
if (!device_property_read_u32(dev, "poll-interval", &value))
input_set_poll_interval(input, value);
error = input_register_device(input);
if (error) { if (error) {
dev_err(dev, "Unable to register input device: %d\n", error); dev_err(dev, "Unable to register input device: %d\n", error);
return error; return error;
......
...@@ -857,70 +857,35 @@ static void adp5589_report_switch_state(struct adp5589_kpad *kpad) ...@@ -857,70 +857,35 @@ static void adp5589_report_switch_state(struct adp5589_kpad *kpad)
input_sync(kpad->input); input_sync(kpad->input);
} }
static int adp5589_probe(struct i2c_client *client, static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
const struct i2c_device_id *id)
{ {
struct adp5589_kpad *kpad; struct i2c_client *client = kpad->client;
const struct adp5589_kpad_platform_data *pdata = const struct adp5589_kpad_platform_data *pdata =
dev_get_platdata(&client->dev); dev_get_platdata(&client->dev);
struct input_dev *input; struct input_dev *input;
unsigned int revid; unsigned int i;
int ret, i;
int error; int error;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
return -EIO;
}
if (!pdata) {
dev_err(&client->dev, "no platform data?\n");
return -EINVAL;
}
kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
if (!kpad)
return -ENOMEM;
switch (id->driver_data) {
case ADP5585_02:
kpad->support_row5 = true;
/* fall through */
case ADP5585_01:
kpad->is_adp5585 = true;
kpad->var = &const_adp5585;
break;
case ADP5589:
kpad->support_row5 = true;
kpad->var = &const_adp5589;
break;
}
if (!((pdata->keypad_en_mask & kpad->var->row_mask) && if (!((pdata->keypad_en_mask & kpad->var->row_mask) &&
(pdata->keypad_en_mask >> kpad->var->col_shift)) || (pdata->keypad_en_mask >> kpad->var->col_shift)) ||
!pdata->keymap) { !pdata->keymap) {
dev_err(&client->dev, "no rows, cols or keymap from pdata\n"); dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
if (pdata->keymapsize != kpad->var->keymapsize) { if (pdata->keymapsize != kpad->var->keymapsize) {
dev_err(&client->dev, "invalid keymapsize\n"); dev_err(&client->dev, "invalid keymapsize\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
if (!pdata->gpimap && pdata->gpimapsize) { if (!pdata->gpimap && pdata->gpimapsize) {
dev_err(&client->dev, "invalid gpimap from pdata\n"); dev_err(&client->dev, "invalid gpimap from pdata\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
if (pdata->gpimapsize > kpad->var->gpimapsize_max) { if (pdata->gpimapsize > kpad->var->gpimapsize_max) {
dev_err(&client->dev, "invalid gpimapsize\n"); dev_err(&client->dev, "invalid gpimapsize\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
for (i = 0; i < pdata->gpimapsize; i++) { for (i = 0; i < pdata->gpimapsize; i++) {
...@@ -929,41 +894,27 @@ static int adp5589_probe(struct i2c_client *client, ...@@ -929,41 +894,27 @@ static int adp5589_probe(struct i2c_client *client,
if (pin < kpad->var->gpi_pin_base || if (pin < kpad->var->gpi_pin_base ||
pin > kpad->var->gpi_pin_end) { pin > kpad->var->gpi_pin_end) {
dev_err(&client->dev, "invalid gpi pin data\n"); dev_err(&client->dev, "invalid gpi pin data\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
if ((1 << (pin - kpad->var->gpi_pin_row_base)) & if ((1 << (pin - kpad->var->gpi_pin_row_base)) &
pdata->keypad_en_mask) { pdata->keypad_en_mask) {
dev_err(&client->dev, "invalid gpi row/col data\n"); dev_err(&client->dev, "invalid gpi row/col data\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
} }
if (!client->irq) { if (!client->irq) {
dev_err(&client->dev, "no IRQ?\n"); dev_err(&client->dev, "no IRQ?\n");
error = -EINVAL; return -EINVAL;
goto err_free_mem;
} }
input = input_allocate_device(); input = input_allocate_device();
if (!input) { if (!input)
error = -ENOMEM; return -ENOMEM;
goto err_free_mem;
}
kpad->client = client;
kpad->input = input; kpad->input = input;
ret = adp5589_read(client, ADP5589_5_ID);
if (ret < 0) {
error = ret;
goto err_free_input;
}
revid = (u8) ret & ADP5589_5_DEVICE_ID_MASK;
input->name = client->name; input->name = client->name;
input->phys = "adp5589-keys/input0"; input->phys = "adp5589-keys/input0";
input->dev.parent = &client->dev; input->dev.parent = &client->dev;
...@@ -1015,30 +966,99 @@ static int adp5589_probe(struct i2c_client *client, ...@@ -1015,30 +966,99 @@ static int adp5589_probe(struct i2c_client *client,
goto err_unreg_dev; goto err_unreg_dev;
} }
device_init_wakeup(&client->dev, 1);
return 0;
err_unreg_dev:
input_unregister_device(input);
input = NULL;
err_free_input:
input_free_device(input);
return error;
}
static void adp5589_keypad_remove(struct adp5589_kpad *kpad)
{
if (kpad->input) {
free_irq(kpad->client->irq, kpad);
input_unregister_device(kpad->input);
}
}
static int adp5589_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adp5589_kpad *kpad;
const struct adp5589_kpad_platform_data *pdata =
dev_get_platdata(&client->dev);
unsigned int revid;
int error, ret;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
return -EIO;
}
if (!pdata) {
dev_err(&client->dev, "no platform data?\n");
return -EINVAL;
}
kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
if (!kpad)
return -ENOMEM;
kpad->client = client;
switch (id->driver_data) {
case ADP5585_02:
kpad->support_row5 = true;
/* fall through */
case ADP5585_01:
kpad->is_adp5585 = true;
kpad->var = &const_adp5585;
break;
case ADP5589:
kpad->support_row5 = true;
kpad->var = &const_adp5589;
break;
}
ret = adp5589_read(client, ADP5589_5_ID);
if (ret < 0) {
error = ret;
goto err_free_mem;
}
revid = (u8) ret & ADP5589_5_DEVICE_ID_MASK;
if (pdata->keymapsize) {
error = adp5589_keypad_add(kpad, revid);
if (error)
goto err_free_mem;
}
error = adp5589_setup(kpad); error = adp5589_setup(kpad);
if (error) if (error)
goto err_free_irq; goto err_keypad_remove;
if (kpad->gpimapsize) if (kpad->gpimapsize)
adp5589_report_switch_state(kpad); adp5589_report_switch_state(kpad);
error = adp5589_gpio_add(kpad); error = adp5589_gpio_add(kpad);
if (error) if (error)
goto err_free_irq; goto err_keypad_remove;
device_init_wakeup(&client->dev, 1);
i2c_set_clientdata(client, kpad); i2c_set_clientdata(client, kpad);
dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq); dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
return 0; return 0;
err_free_irq: err_keypad_remove:
free_irq(client->irq, kpad); adp5589_keypad_remove(kpad);
err_unreg_dev:
input_unregister_device(input);
input = NULL;
err_free_input:
input_free_device(input);
err_free_mem: err_free_mem:
kfree(kpad); kfree(kpad);
...@@ -1050,8 +1070,7 @@ static int adp5589_remove(struct i2c_client *client) ...@@ -1050,8 +1070,7 @@ static int adp5589_remove(struct i2c_client *client)
struct adp5589_kpad *kpad = i2c_get_clientdata(client); struct adp5589_kpad *kpad = i2c_get_clientdata(client);
adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0); adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
free_irq(client->irq, kpad); adp5589_keypad_remove(kpad);
input_unregister_device(kpad->input);
adp5589_gpio_remove(kpad); adp5589_gpio_remove(kpad);
kfree(kpad); kfree(kpad);
...@@ -1064,6 +1083,9 @@ static int adp5589_suspend(struct device *dev) ...@@ -1064,6 +1083,9 @@ static int adp5589_suspend(struct device *dev)
struct adp5589_kpad *kpad = dev_get_drvdata(dev); struct adp5589_kpad *kpad = dev_get_drvdata(dev);
struct i2c_client *client = kpad->client; struct i2c_client *client = kpad->client;
if (!kpad->input)
return 0;
disable_irq(client->irq); disable_irq(client->irq);
if (device_may_wakeup(&client->dev)) if (device_may_wakeup(&client->dev))
...@@ -1077,6 +1099,9 @@ static int adp5589_resume(struct device *dev) ...@@ -1077,6 +1099,9 @@ static int adp5589_resume(struct device *dev)
struct adp5589_kpad *kpad = dev_get_drvdata(dev); struct adp5589_kpad *kpad = dev_get_drvdata(dev);
struct i2c_client *client = kpad->client; struct i2c_client *client = kpad->client;
if (!kpad->input)
return 0;
if (device_may_wakeup(&client->dev)) if (device_may_wakeup(&client->dev))
disable_irq_wake(client->irq); disable_irq_wake(client->irq);
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -30,10 +29,10 @@ struct clps711x_keypad_data { ...@@ -30,10 +29,10 @@ struct clps711x_keypad_data {
struct clps711x_gpio_data *gpio_data; struct clps711x_gpio_data *gpio_data;
}; };
static void clps711x_keypad_poll(struct input_polled_dev *dev) static void clps711x_keypad_poll(struct input_dev *input)
{ {
const unsigned short *keycodes = dev->input->keycode; const unsigned short *keycodes = input->keycode;
struct clps711x_keypad_data *priv = dev->private; struct clps711x_keypad_data *priv = input_get_drvdata(input);
bool sync = false; bool sync = false;
int col, row; int col, row;
...@@ -61,14 +60,14 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev) ...@@ -61,14 +60,14 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev)
if (state) { if (state) {
set_bit(col, data->last_state); set_bit(col, data->last_state);
input_event(dev->input, EV_MSC, input_event(input,
MSC_SCAN, code); EV_MSC, MSC_SCAN, code);
} else { } else {
clear_bit(col, data->last_state); clear_bit(col, data->last_state);
} }
if (keycodes[code]) if (keycodes[code])
input_report_key(dev->input, input_report_key(input,
keycodes[code], state); keycodes[code], state);
sync = true; sync = true;
} }
...@@ -80,7 +79,7 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev) ...@@ -80,7 +79,7 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev)
} }
if (sync) if (sync)
input_sync(dev->input); input_sync(input);
} }
static int clps711x_keypad_probe(struct platform_device *pdev) static int clps711x_keypad_probe(struct platform_device *pdev)
...@@ -88,7 +87,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev) ...@@ -88,7 +87,7 @@ static int clps711x_keypad_probe(struct platform_device *pdev)
struct clps711x_keypad_data *priv; struct clps711x_keypad_data *priv;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct input_polled_dev *poll_dev; struct input_dev *input;
u32 poll_interval; u32 poll_interval;
int i, err; int i, err;
...@@ -125,53 +124,43 @@ static int clps711x_keypad_probe(struct platform_device *pdev) ...@@ -125,53 +124,43 @@ static int clps711x_keypad_probe(struct platform_device *pdev)
if (err) if (err)
return err; return err;
poll_dev = input_allocate_polled_device(); input = devm_input_allocate_device(dev);
if (!poll_dev) if (!input)
return -ENOMEM; return -ENOMEM;
poll_dev->private = priv; input_set_drvdata(input, priv);
poll_dev->poll = clps711x_keypad_poll;
poll_dev->poll_interval = poll_interval; input->name = pdev->name;
poll_dev->input->name = pdev->name; input->dev.parent = dev;
poll_dev->input->dev.parent = dev; input->id.bustype = BUS_HOST;
poll_dev->input->id.bustype = BUS_HOST; input->id.vendor = 0x0001;
poll_dev->input->id.vendor = 0x0001; input->id.product = 0x0001;
poll_dev->input->id.product = 0x0001; input->id.version = 0x0100;
poll_dev->input->id.version = 0x0100;
err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count, err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count,
CLPS711X_KEYPAD_COL_COUNT, CLPS711X_KEYPAD_COL_COUNT,
NULL, poll_dev->input); NULL, input);
if (err) if (err)
goto out_err; return err;
input_set_capability(poll_dev->input, EV_MSC, MSC_SCAN); input_set_capability(input, EV_MSC, MSC_SCAN);
if (of_property_read_bool(np, "autorepeat")) if (of_property_read_bool(np, "autorepeat"))
__set_bit(EV_REP, poll_dev->input->evbit); __set_bit(EV_REP, input->evbit);
platform_set_drvdata(pdev, poll_dev);
/* Set all columns to low */ /* Set all columns to low */
regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK, regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK,
SYSCON1_KBDSCAN(1)); SYSCON1_KBDSCAN(1));
err = input_register_polled_device(poll_dev);
if (err)
goto out_err;
return 0;
out_err: err = input_setup_polling(input, clps711x_keypad_poll);
input_free_polled_device(poll_dev); if (err)
return err; return err;
}
static int clps711x_keypad_remove(struct platform_device *pdev) input_set_poll_interval(input, poll_interval);
{
struct input_polled_dev *poll_dev = platform_get_drvdata(pdev);
input_unregister_polled_device(poll_dev); err = input_register_device(input);
input_free_polled_device(poll_dev); if (err)
return err;
return 0; return 0;
} }
...@@ -188,7 +177,6 @@ static struct platform_driver clps711x_keypad_driver = { ...@@ -188,7 +177,6 @@ static struct platform_driver clps711x_keypad_driver = {
.of_match_table = clps711x_keypad_of_match, .of_match_table = clps711x_keypad_of_match,
}, },
.probe = clps711x_keypad_probe, .probe = clps711x_keypad_probe,
.remove = clps711x_keypad_remove,
}; };
module_platform_driver(clps711x_keypad_driver); module_platform_driver(clps711x_keypad_driver);
......
...@@ -494,10 +494,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev, ...@@ -494,10 +494,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
spin_lock_init(&bdata->lock); spin_lock_init(&bdata->lock);
if (child) { if (child) {
bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL, bdata->gpiod = devm_fwnode_gpiod_get(dev, child,
child, NULL, GPIOD_IN, desc);
GPIOD_IN,
desc);
if (IS_ERR(bdata->gpiod)) { if (IS_ERR(bdata->gpiod)) {
error = PTR_ERR(bdata->gpiod); error = PTR_ERR(bdata->gpiod);
if (error == -ENOENT) { if (error == -ENOENT) {
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -34,7 +33,7 @@ struct gpio_keys_button_data { ...@@ -34,7 +33,7 @@ struct gpio_keys_button_data {
}; };
struct gpio_keys_polled_dev { struct gpio_keys_polled_dev {
struct input_polled_dev *poll_dev; struct input_dev *input;
struct device *dev; struct device *dev;
const struct gpio_keys_platform_data *pdata; const struct gpio_keys_platform_data *pdata;
unsigned long rel_axis_seen[BITS_TO_LONGS(REL_CNT)]; unsigned long rel_axis_seen[BITS_TO_LONGS(REL_CNT)];
...@@ -42,12 +41,11 @@ struct gpio_keys_polled_dev { ...@@ -42,12 +41,11 @@ struct gpio_keys_polled_dev {
struct gpio_keys_button_data data[0]; struct gpio_keys_button_data data[0];
}; };
static void gpio_keys_button_event(struct input_polled_dev *dev, static void gpio_keys_button_event(struct input_dev *input,
const struct gpio_keys_button *button, const struct gpio_keys_button *button,
int state) int state)
{ {
struct gpio_keys_polled_dev *bdev = dev->private; struct gpio_keys_polled_dev *bdev = input_get_drvdata(input);
struct input_dev *input = dev->input;
unsigned int type = button->type ?: EV_KEY; unsigned int type = button->type ?: EV_KEY;
if (type == EV_REL) { if (type == EV_REL) {
...@@ -66,7 +64,7 @@ static void gpio_keys_button_event(struct input_polled_dev *dev, ...@@ -66,7 +64,7 @@ static void gpio_keys_button_event(struct input_polled_dev *dev,
} }
} }
static void gpio_keys_polled_check_state(struct input_polled_dev *dev, static void gpio_keys_polled_check_state(struct input_dev *input,
const struct gpio_keys_button *button, const struct gpio_keys_button *button,
struct gpio_keys_button_data *bdata) struct gpio_keys_button_data *bdata)
{ {
...@@ -74,10 +72,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev, ...@@ -74,10 +72,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev,
state = gpiod_get_value_cansleep(bdata->gpiod); state = gpiod_get_value_cansleep(bdata->gpiod);
if (state < 0) { if (state < 0) {
dev_err(dev->input->dev.parent, dev_err(input->dev.parent,
"failed to get gpio state: %d\n", state); "failed to get gpio state: %d\n", state);
} else { } else {
gpio_keys_button_event(dev, button, state); gpio_keys_button_event(input, button, state);
if (state != bdata->last_state) { if (state != bdata->last_state) {
bdata->count = 0; bdata->count = 0;
...@@ -86,11 +84,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev, ...@@ -86,11 +84,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev,
} }
} }
static void gpio_keys_polled_poll(struct input_polled_dev *dev) static void gpio_keys_polled_poll(struct input_dev *input)
{ {
struct gpio_keys_polled_dev *bdev = dev->private; struct gpio_keys_polled_dev *bdev = input_get_drvdata(input);
const struct gpio_keys_platform_data *pdata = bdev->pdata; const struct gpio_keys_platform_data *pdata = bdev->pdata;
struct input_dev *input = dev->input;
int i; int i;
memset(bdev->rel_axis_seen, 0, sizeof(bdev->rel_axis_seen)); memset(bdev->rel_axis_seen, 0, sizeof(bdev->rel_axis_seen));
...@@ -101,10 +98,10 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev) ...@@ -101,10 +98,10 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev)
if (bdata->count < bdata->threshold) { if (bdata->count < bdata->threshold) {
bdata->count++; bdata->count++;
gpio_keys_button_event(dev, &pdata->buttons[i], gpio_keys_button_event(input, &pdata->buttons[i],
bdata->last_state); bdata->last_state);
} else { } else {
gpio_keys_polled_check_state(dev, &pdata->buttons[i], gpio_keys_polled_check_state(input, &pdata->buttons[i],
bdata); bdata);
} }
} }
...@@ -122,18 +119,20 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev) ...@@ -122,18 +119,20 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev)
input_sync(input); input_sync(input);
} }
static void gpio_keys_polled_open(struct input_polled_dev *dev) static int gpio_keys_polled_open(struct input_dev *input)
{ {
struct gpio_keys_polled_dev *bdev = dev->private; struct gpio_keys_polled_dev *bdev = input_get_drvdata(input);
const struct gpio_keys_platform_data *pdata = bdev->pdata; const struct gpio_keys_platform_data *pdata = bdev->pdata;
if (pdata->enable) if (pdata->enable)
pdata->enable(bdev->dev); pdata->enable(bdev->dev);
return 0;
} }
static void gpio_keys_polled_close(struct input_polled_dev *dev) static void gpio_keys_polled_close(struct input_dev *input)
{ {
struct gpio_keys_polled_dev *bdev = dev->private; struct gpio_keys_polled_dev *bdev = input_get_drvdata(input);
const struct gpio_keys_platform_data *pdata = bdev->pdata; const struct gpio_keys_platform_data *pdata = bdev->pdata;
if (pdata->disable) if (pdata->disable)
...@@ -232,7 +231,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) ...@@ -232,7 +231,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
struct fwnode_handle *child = NULL; struct fwnode_handle *child = NULL;
const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev); const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
struct gpio_keys_polled_dev *bdev; struct gpio_keys_polled_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input; struct input_dev *input;
int error; int error;
int i; int i;
...@@ -255,19 +253,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) ...@@ -255,19 +253,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
poll_dev = devm_input_allocate_polled_device(dev); input = devm_input_allocate_device(dev);
if (!poll_dev) { if (!input) {
dev_err(dev, "no memory for polled device\n"); dev_err(dev, "no memory for input device\n");
return -ENOMEM; return -ENOMEM;
} }
poll_dev->private = bdev; input_set_drvdata(input, bdev);
poll_dev->poll = gpio_keys_polled_poll;
poll_dev->poll_interval = pdata->poll_interval;
poll_dev->open = gpio_keys_polled_open;
poll_dev->close = gpio_keys_polled_close;
input = poll_dev->input;
input->name = pdata->name ?: pdev->name; input->name = pdata->name ?: pdev->name;
input->phys = DRV_NAME"/input0"; input->phys = DRV_NAME"/input0";
...@@ -277,6 +269,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) ...@@ -277,6 +269,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
input->id.product = 0x0001; input->id.product = 0x0001;
input->id.version = 0x0100; input->id.version = 0x0100;
input->open = gpio_keys_polled_open;
input->close = gpio_keys_polled_close;
__set_bit(EV_KEY, input->evbit); __set_bit(EV_KEY, input->evbit);
if (pdata->rep) if (pdata->rep)
__set_bit(EV_REP, input->evbit); __set_bit(EV_REP, input->evbit);
...@@ -300,10 +295,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) ...@@ -300,10 +295,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, bdata->gpiod = devm_fwnode_gpiod_get(dev, child,
NULL, child, NULL, GPIOD_IN,
GPIOD_IN, button->desc);
button->desc);
if (IS_ERR(bdata->gpiod)) { if (IS_ERR(bdata->gpiod)) {
error = PTR_ERR(bdata->gpiod); error = PTR_ERR(bdata->gpiod);
if (error != -EPROBE_DEFER) if (error != -EPROBE_DEFER)
...@@ -353,11 +347,19 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) ...@@ -353,11 +347,19 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
fwnode_handle_put(child); fwnode_handle_put(child);
bdev->poll_dev = poll_dev; bdev->input = input;
bdev->dev = dev; bdev->dev = dev;
bdev->pdata = pdata; bdev->pdata = pdata;
error = input_register_polled_device(poll_dev); error = input_setup_polling(input, gpio_keys_polled_poll);
if (error) {
dev_err(dev, "unable to set up polling, err=%d\n", error);
return error;
}
input_set_poll_interval(input, pdata->poll_interval);
error = input_register_device(input);
if (error) { if (error) {
dev_err(dev, "unable to register polled device, err=%d\n", dev_err(dev, "unable to register polled device, err=%d\n",
error); error);
...@@ -366,7 +368,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) ...@@ -366,7 +368,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
/* report initial state of the buttons */ /* report initial state of the buttons */
for (i = 0; i < pdata->nbuttons; i++) for (i = 0; i < pdata->nbuttons; i++)
gpio_keys_polled_check_state(poll_dev, &pdata->buttons[i], gpio_keys_polled_check_state(input, &pdata->buttons[i],
&bdev->data[i]); &bdev->data[i]);
input_sync(input); input_sync(input);
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2019 NXP.
*/
#include <linux/err.h>
#include <linux/device.h>
#include <linux/firmware/imx/sci.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#define DEBOUNCE_TIME 30
#define REPEAT_INTERVAL 60
#define SC_IRQ_BUTTON 1
#define SC_IRQ_GROUP_WAKE 3
#define IMX_SC_MISC_FUNC_GET_BUTTON_STATUS 18
struct imx_key_drv_data {
u32 keycode;
bool keystate; /* true: pressed, false: released */
struct delayed_work check_work;
struct input_dev *input;
struct imx_sc_ipc *key_ipc_handle;
struct notifier_block key_notifier;
};
struct imx_sc_msg_key {
struct imx_sc_rpc_msg hdr;
u32 state;
};
static int imx_sc_key_notify(struct notifier_block *nb,
unsigned long event, void *group)
{
struct imx_key_drv_data *priv =
container_of(nb,
struct imx_key_drv_data,
key_notifier);
if ((event & SC_IRQ_BUTTON) && (*(u8 *)group == SC_IRQ_GROUP_WAKE)) {
schedule_delayed_work(&priv->check_work,
msecs_to_jiffies(DEBOUNCE_TIME));
pm_wakeup_event(priv->input->dev.parent, 0);
}
return 0;
}
static void imx_sc_check_for_events(struct work_struct *work)
{
struct imx_key_drv_data *priv =
container_of(work,
struct imx_key_drv_data,
check_work.work);
struct input_dev *input = priv->input;
struct imx_sc_msg_key msg;
struct imx_sc_rpc_msg *hdr = &msg.hdr;
bool state;
int error;
hdr->ver = IMX_SC_RPC_VERSION;
hdr->svc = IMX_SC_RPC_SVC_MISC;
hdr->func = IMX_SC_MISC_FUNC_GET_BUTTON_STATUS;
hdr->size = 1;
error = imx_scu_call_rpc(priv->key_ipc_handle, &msg, true);
if (error) {
dev_err(&input->dev, "read imx sc key failed, error %d\n", error);
return;
}
state = (bool)msg.state;
if (state ^ priv->keystate) {
priv->keystate = state;
input_event(input, EV_KEY, priv->keycode, state);
input_sync(input);
if (!priv->keystate)
pm_relax(priv->input->dev.parent);
}
if (state)
schedule_delayed_work(&priv->check_work,
msecs_to_jiffies(REPEAT_INTERVAL));
}
static int imx_sc_key_probe(struct platform_device *pdev)
{
struct imx_key_drv_data *priv;
struct input_dev *input;
int error;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
error = imx_scu_get_handle(&priv->key_ipc_handle);
if (error)
return error;
if (device_property_read_u32(&pdev->dev, "linux,keycodes",
&priv->keycode)) {
dev_err(&pdev->dev, "missing linux,keycodes property\n");
return -EINVAL;
}
INIT_DELAYED_WORK(&priv->check_work, imx_sc_check_for_events);
input = devm_input_allocate_device(&pdev->dev);
if (!input) {
dev_err(&pdev->dev, "failed to allocate the input device\n");
return -ENOMEM;
}
input->name = pdev->name;
input->phys = "imx-sc-key/input0";
input->id.bustype = BUS_HOST;
input_set_capability(input, EV_KEY, priv->keycode);
error = input_register_device(input);
if (error) {
dev_err(&pdev->dev, "failed to register input device\n");
return error;
}
priv->input = input;
platform_set_drvdata(pdev, priv);
error = imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON,
true);
if (error) {
dev_err(&pdev->dev, "failed to enable scu group irq\n");
return error;
}
priv->key_notifier.notifier_call = imx_sc_key_notify;
error = imx_scu_irq_register_notifier(&priv->key_notifier);
if (error) {
imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON,
false);
dev_err(&pdev->dev, "failed to register scu notifier\n");
return error;
}
return 0;
}
static int imx_sc_key_remove(struct platform_device *pdev)
{
struct imx_key_drv_data *priv = platform_get_drvdata(pdev);
imx_scu_irq_group_enable(SC_IRQ_GROUP_WAKE, SC_IRQ_BUTTON, false);
imx_scu_irq_unregister_notifier(&priv->key_notifier);
cancel_delayed_work_sync(&priv->check_work);
return 0;
}
static const struct of_device_id imx_sc_key_ids[] = {
{ .compatible = "fsl,imx-sc-key" },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_sc_key_ids);
static struct platform_driver imx_sc_key_driver = {
.driver = {
.name = "imx-sc-key",
.of_match_table = imx_sc_key_ids,
},
.probe = imx_sc_key_probe,
.remove = imx_sc_key_remove,
};
module_platform_driver(imx_sc_key_driver);
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
MODULE_DESCRIPTION("i.MX System Controller Key Driver");
MODULE_LICENSE("GPL v2");
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -64,7 +63,7 @@ static const unsigned short jornada_scancodes[] = { ...@@ -64,7 +63,7 @@ static const unsigned short jornada_scancodes[] = {
#define JORNADA_SCAN_SIZE 18 #define JORNADA_SCAN_SIZE 18
struct jornadakbd { struct jornadakbd {
struct input_polled_dev *poll_dev; struct input_dev *input;
unsigned short keymap[ARRAY_SIZE(jornada_scancodes)]; unsigned short keymap[ARRAY_SIZE(jornada_scancodes)];
unsigned char length; unsigned char length;
unsigned char old_scan[JORNADA_SCAN_SIZE]; unsigned char old_scan[JORNADA_SCAN_SIZE];
...@@ -73,7 +72,7 @@ struct jornadakbd { ...@@ -73,7 +72,7 @@ struct jornadakbd {
static void jornada_parse_kbd(struct jornadakbd *jornadakbd) static void jornada_parse_kbd(struct jornadakbd *jornadakbd)
{ {
struct input_dev *input_dev = jornadakbd->poll_dev->input; struct input_dev *input_dev = jornadakbd->input;
unsigned short *keymap = jornadakbd->keymap; unsigned short *keymap = jornadakbd->keymap;
unsigned int sync_me = 0; unsigned int sync_me = 0;
unsigned int i, j; unsigned int i, j;
...@@ -167,9 +166,9 @@ static void jornada_scan_keyb(unsigned char *s) ...@@ -167,9 +166,9 @@ static void jornada_scan_keyb(unsigned char *s)
*s++ = __raw_readb(PHDR); *s++ = __raw_readb(PHDR);
} }
static void jornadakbd680_poll(struct input_polled_dev *dev) static void jornadakbd680_poll(struct input_dev *input)
{ {
struct jornadakbd *jornadakbd = dev->private; struct jornadakbd *jornadakbd = input_get_drvdata(input);
jornada_scan_keyb(jornadakbd->new_scan); jornada_scan_keyb(jornadakbd->new_scan);
jornada_parse_kbd(jornadakbd); jornada_parse_kbd(jornadakbd);
...@@ -179,7 +178,6 @@ static void jornadakbd680_poll(struct input_polled_dev *dev) ...@@ -179,7 +178,6 @@ static void jornadakbd680_poll(struct input_polled_dev *dev)
static int jornada680kbd_probe(struct platform_device *pdev) static int jornada680kbd_probe(struct platform_device *pdev)
{ {
struct jornadakbd *jornadakbd; struct jornadakbd *jornadakbd;
struct input_polled_dev *poll_dev;
struct input_dev *input_dev; struct input_dev *input_dev;
int i, error; int i, error;
...@@ -188,29 +186,24 @@ static int jornada680kbd_probe(struct platform_device *pdev) ...@@ -188,29 +186,24 @@ static int jornada680kbd_probe(struct platform_device *pdev)
if (!jornadakbd) if (!jornadakbd)
return -ENOMEM; return -ENOMEM;
poll_dev = devm_input_allocate_polled_device(&pdev->dev); input_dev = devm_input_allocate_device(&pdev->dev);
if (!poll_dev) { if (!input_dev) {
dev_err(&pdev->dev, "failed to allocate polled input device\n"); dev_err(&pdev->dev, "failed to allocate input device\n");
return -ENOMEM; return -ENOMEM;
} }
jornadakbd->poll_dev = poll_dev; jornadakbd->input = input_dev;
memcpy(jornadakbd->keymap, jornada_scancodes, memcpy(jornadakbd->keymap, jornada_scancodes,
sizeof(jornadakbd->keymap)); sizeof(jornadakbd->keymap));
poll_dev->private = jornadakbd; input_set_drvdata(input_dev, jornadakbd);
poll_dev->poll = jornadakbd680_poll;
poll_dev->poll_interval = 50; /* msec */
input_dev = poll_dev->input;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->name = "HP Jornada 680 keyboard"; input_dev->name = "HP Jornada 680 keyboard";
input_dev->phys = "jornadakbd/input0"; input_dev->phys = "jornadakbd/input0";
input_dev->keycode = jornadakbd->keymap; input_dev->keycode = jornadakbd->keymap;
input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodesize = sizeof(unsigned short);
input_dev->keycodemax = ARRAY_SIZE(jornada_scancodes); input_dev->keycodemax = ARRAY_SIZE(jornada_scancodes);
input_dev->dev.parent = &pdev->dev;
input_dev->id.bustype = BUS_HOST; input_dev->id.bustype = BUS_HOST;
for (i = 0; i < 128; i++) for (i = 0; i < 128; i++)
...@@ -220,9 +213,17 @@ static int jornada680kbd_probe(struct platform_device *pdev) ...@@ -220,9 +213,17 @@ static int jornada680kbd_probe(struct platform_device *pdev)
input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_capability(input_dev, EV_MSC, MSC_SCAN);
error = input_register_polled_device(jornadakbd->poll_dev); error = input_setup_polling(input_dev, jornadakbd680_poll);
if (error) {
dev_err(&pdev->dev, "failed to set up polling\n");
return error;
}
input_set_poll_interval(input_dev, 50 /* msec */);
error = input_register_device(input_dev);
if (error) { if (error) {
dev_err(&pdev->dev, "failed to register polled input device\n"); dev_err(&pdev->dev, "failed to register input device\n");
return error; return error;
} }
......
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
/* MPR121 has 12 keys */ /* MPR121 has 12 keys */
#define MPR121_MAX_KEY_COUNT 12 #define MPR121_MAX_KEY_COUNT 12
#define MPR121_MIN_POLL_INTERVAL 10
#define MPR121_MAX_POLL_INTERVAL 200
struct mpr121_touchkey { struct mpr121_touchkey {
struct i2c_client *client; struct i2c_client *client;
struct input_dev *input_dev; struct input_dev *input_dev;
...@@ -115,11 +118,11 @@ static struct regulator *mpr121_vdd_supply_init(struct device *dev) ...@@ -115,11 +118,11 @@ static struct regulator *mpr121_vdd_supply_init(struct device *dev)
return vdd_supply; return vdd_supply;
} }
static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) static void mpr_touchkey_report(struct input_dev *dev)
{ {
struct mpr121_touchkey *mpr121 = dev_id; struct mpr121_touchkey *mpr121 = input_get_drvdata(dev);
struct i2c_client *client = mpr121->client;
struct input_dev *input = mpr121->input_dev; struct input_dev *input = mpr121->input_dev;
struct i2c_client *client = mpr121->client;
unsigned long bit_changed; unsigned long bit_changed;
unsigned int key_num; unsigned int key_num;
int reg; int reg;
...@@ -127,14 +130,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) ...@@ -127,14 +130,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
if (reg < 0) { if (reg < 0) {
dev_err(&client->dev, "i2c read error [%d]\n", reg); dev_err(&client->dev, "i2c read error [%d]\n", reg);
goto out; return;
} }
reg <<= 8; reg <<= 8;
reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR); reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR);
if (reg < 0) { if (reg < 0) {
dev_err(&client->dev, "i2c read error [%d]\n", reg); dev_err(&client->dev, "i2c read error [%d]\n", reg);
goto out; return;
} }
reg &= TOUCH_STATUS_MASK; reg &= TOUCH_STATUS_MASK;
...@@ -155,8 +158,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) ...@@ -155,8 +158,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
} }
input_sync(input); input_sync(input);
}
static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
{
struct mpr121_touchkey *mpr121 = dev_id;
mpr_touchkey_report(mpr121->input_dev);
out:
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -229,14 +238,10 @@ static int mpr_touchkey_probe(struct i2c_client *client, ...@@ -229,14 +238,10 @@ static int mpr_touchkey_probe(struct i2c_client *client,
int vdd_uv; int vdd_uv;
struct mpr121_touchkey *mpr121; struct mpr121_touchkey *mpr121;
struct input_dev *input_dev; struct input_dev *input_dev;
u32 poll_interval = 0;
int error; int error;
int i; int i;
if (!client->irq) {
dev_err(dev, "irq number should not be zero\n");
return -EINVAL;
}
vdd_supply = mpr121_vdd_supply_init(dev); vdd_supply = mpr121_vdd_supply_init(dev);
if (IS_ERR(vdd_supply)) if (IS_ERR(vdd_supply))
return PTR_ERR(vdd_supply); return PTR_ERR(vdd_supply);
...@@ -274,6 +279,7 @@ static int mpr_touchkey_probe(struct i2c_client *client, ...@@ -274,6 +279,7 @@ static int mpr_touchkey_probe(struct i2c_client *client,
if (device_property_read_bool(dev, "autorepeat")) if (device_property_read_bool(dev, "autorepeat"))
__set_bit(EV_REP, input_dev->evbit); __set_bit(EV_REP, input_dev->evbit);
input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_set_drvdata(input_dev, mpr121);
input_dev->keycode = mpr121->keycodes; input_dev->keycode = mpr121->keycodes;
input_dev->keycodesize = sizeof(mpr121->keycodes[0]); input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
...@@ -288,13 +294,40 @@ static int mpr_touchkey_probe(struct i2c_client *client, ...@@ -288,13 +294,40 @@ static int mpr_touchkey_probe(struct i2c_client *client,
return error; return error;
} }
error = devm_request_threaded_irq(dev, client->irq, NULL, device_property_read_u32(dev, "poll-interval", &poll_interval);
mpr_touchkey_interrupt,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT, if (client->irq) {
dev->driver->name, mpr121); error = devm_request_threaded_irq(dev, client->irq, NULL,
if (error) { mpr_touchkey_interrupt,
dev_err(dev, "Failed to register interrupt\n"); IRQF_TRIGGER_FALLING |
return error; IRQF_ONESHOT,
dev->driver->name, mpr121);
if (error) {
dev_err(dev, "Failed to register interrupt\n");
return error;
}
} else if (poll_interval) {
if (poll_interval < MPR121_MIN_POLL_INTERVAL)
return -EINVAL;
if (poll_interval > MPR121_MAX_POLL_INTERVAL)
return -EINVAL;
error = input_setup_polling(input_dev, mpr_touchkey_report);
if (error) {
dev_err(dev, "Failed to setup polling\n");
return error;
}
input_set_poll_interval(input_dev, poll_interval);
input_set_min_poll_interval(input_dev,
MPR121_MIN_POLL_INTERVAL);
input_set_max_poll_interval(input_dev,
MPR121_MAX_POLL_INTERVAL);
} else {
dev_err(dev,
"invalid IRQ number and polling not configured\n");
return -EINVAL;
} }
error = input_register_device(input_dev); error = input_register_device(input_dev);
......
...@@ -100,7 +100,6 @@ config INPUT_ATMEL_CAPTOUCH ...@@ -100,7 +100,6 @@ config INPUT_ATMEL_CAPTOUCH
config INPUT_BMA150 config INPUT_BMA150
tristate "BMA150/SMB380 acceleration sensor support" tristate "BMA150/SMB380 acceleration sensor support"
depends on I2C depends on I2C
select INPUT_POLLDEV
help help
Say Y here if you have Bosch Sensortec's BMA150 or SMB380 Say Y here if you have Bosch Sensortec's BMA150 or SMB380
acceleration sensor hooked to an I2C bus. acceleration sensor hooked to an I2C bus.
...@@ -246,7 +245,6 @@ config INPUT_MC13783_PWRBUTTON ...@@ -246,7 +245,6 @@ config INPUT_MC13783_PWRBUTTON
config INPUT_MMA8450 config INPUT_MMA8450
tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer" tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer"
depends on I2C depends on I2C
select INPUT_POLLDEV
help help
Say Y here if you want to support Freescale's MMA8450 Accelerometer Say Y here if you want to support Freescale's MMA8450 Accelerometer
through I2C interface. through I2C interface.
...@@ -257,7 +255,6 @@ config INPUT_MMA8450 ...@@ -257,7 +255,6 @@ config INPUT_MMA8450
config INPUT_APANEL config INPUT_APANEL
tristate "Fujitsu Lifebook Application Panel buttons" tristate "Fujitsu Lifebook Application Panel buttons"
depends on X86 && I2C && LEDS_CLASS depends on X86 && I2C && LEDS_CLASS
select INPUT_POLLDEV
select CHECK_SIGNATURE select CHECK_SIGNATURE
help help
Say Y here for support of the Application Panel buttons, used on Say Y here for support of the Application Panel buttons, used on
...@@ -291,7 +288,6 @@ config INPUT_GPIO_BEEPER ...@@ -291,7 +288,6 @@ config INPUT_GPIO_BEEPER
config INPUT_GPIO_DECODER config INPUT_GPIO_DECODER
tristate "Polled GPIO Decoder Input driver" tristate "Polled GPIO Decoder Input driver"
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
select INPUT_POLLDEV
help help
Say Y here if you want driver to read status of multiple GPIO Say Y here if you want driver to read status of multiple GPIO
lines and report the encoded value as an absolute integer to lines and report the encoded value as an absolute integer to
...@@ -327,7 +323,6 @@ config INPUT_IXP4XX_BEEPER ...@@ -327,7 +323,6 @@ config INPUT_IXP4XX_BEEPER
config INPUT_COBALT_BTNS config INPUT_COBALT_BTNS
tristate "Cobalt button interface" tristate "Cobalt button interface"
depends on MIPS_COBALT depends on MIPS_COBALT
select INPUT_POLLDEV
help help
Say Y here if you want to support MIPS Cobalt button interface. Say Y here if you want to support MIPS Cobalt button interface.
...@@ -347,7 +342,6 @@ config INPUT_CPCAP_PWRBUTTON ...@@ -347,7 +342,6 @@ config INPUT_CPCAP_PWRBUTTON
config INPUT_WISTRON_BTNS config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface" tristate "x86 Wistron laptop button interface"
depends on X86_32 depends on X86_32
select INPUT_POLLDEV
select INPUT_SPARSEKMAP select INPUT_SPARSEKMAP
select NEW_LEDS select NEW_LEDS
select LEDS_CLASS select LEDS_CLASS
...@@ -410,13 +404,6 @@ config INPUT_KXTJ9 ...@@ -410,13 +404,6 @@ config INPUT_KXTJ9
To compile this driver as a module, choose M here: the module will To compile this driver as a module, choose M here: the module will
be called kxtj9. be called kxtj9.
config INPUT_KXTJ9_POLLED_MODE
bool "Enable polling mode support"
depends on INPUT_KXTJ9
select INPUT_POLLDEV
help
Say Y here if you need accelerometer to work in polling mode.
config INPUT_POWERMATE config INPUT_POWERMATE
tristate "Griffin PowerMate and Contour Jog support" tristate "Griffin PowerMate and Contour Jog support"
depends on USB_ARCH_HAS_HCD depends on USB_ARCH_HAS_HCD
...@@ -546,7 +533,6 @@ config INPUT_UINPUT ...@@ -546,7 +533,6 @@ config INPUT_UINPUT
config INPUT_SGI_BTNS config INPUT_SGI_BTNS
tristate "SGI Indy/O2 volume button interface" tristate "SGI Indy/O2 volume button interface"
depends on SGI_IP22 || SGI_IP32 depends on SGI_IP22 || SGI_IP32
select INPUT_POLLDEV
help help
Say Y here if you want to support SGI Indy/O2 volume button interface. Say Y here if you want to support SGI Indy/O2 volume button interface.
...@@ -637,7 +623,6 @@ config INPUT_RB532_BUTTON ...@@ -637,7 +623,6 @@ config INPUT_RB532_BUTTON
tristate "Mikrotik Routerboard 532 button interface" tristate "Mikrotik Routerboard 532 button interface"
depends on MIKROTIK_RB532 depends on MIKROTIK_RB532
depends on GPIOLIB depends on GPIOLIB
select INPUT_POLLDEV
help help
Say Y here if you want support for the S1 button built into Say Y here if you want support for the S1 button built into
Mikrotik's Routerboard 532. Mikrotik's Routerboard 532.
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/leds.h> #include <linux/leds.h>
...@@ -51,19 +51,28 @@ static enum apanel_chip device_chip[APANEL_DEV_MAX]; ...@@ -51,19 +51,28 @@ static enum apanel_chip device_chip[APANEL_DEV_MAX];
#define MAX_PANEL_KEYS 12 #define MAX_PANEL_KEYS 12
struct apanel { struct apanel {
struct input_polled_dev *ipdev; struct input_dev *idev;
struct i2c_client *client; struct i2c_client *client;
unsigned short keymap[MAX_PANEL_KEYS]; unsigned short keymap[MAX_PANEL_KEYS];
u16 nkeys; u16 nkeys;
struct led_classdev mail_led; struct led_classdev mail_led;
}; };
static const unsigned short apanel_keymap[MAX_PANEL_KEYS] = {
[0] = KEY_MAIL,
[1] = KEY_WWW,
[2] = KEY_PROG2,
[3] = KEY_PROG1,
static int apanel_probe(struct i2c_client *, const struct i2c_device_id *); [8] = KEY_FORWARD,
[9] = KEY_REWIND,
[10] = KEY_STOPCD,
[11] = KEY_PLAYPAUSE,
};
static void report_key(struct input_dev *input, unsigned keycode) static void report_key(struct input_dev *input, unsigned keycode)
{ {
pr_debug(APANEL ": report key %#x\n", keycode); dev_dbg(input->dev.parent, "report key %#x\n", keycode);
input_report_key(input, keycode, 1); input_report_key(input, keycode, 1);
input_sync(input); input_sync(input);
...@@ -79,10 +88,9 @@ static void report_key(struct input_dev *input, unsigned keycode) ...@@ -79,10 +88,9 @@ static void report_key(struct input_dev *input, unsigned keycode)
* CD keys: * CD keys:
* Forward (0x100), Rewind (0x200), Stop (0x400), Pause (0x800) * Forward (0x100), Rewind (0x200), Stop (0x400), Pause (0x800)
*/ */
static void apanel_poll(struct input_polled_dev *ipdev) static void apanel_poll(struct input_dev *idev)
{ {
struct apanel *ap = ipdev->private; struct apanel *ap = input_get_drvdata(idev);
struct input_dev *idev = ipdev->input;
u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8; u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
s32 data; s32 data;
int i; int i;
...@@ -112,126 +120,93 @@ static int mail_led_set(struct led_classdev *led, ...@@ -112,126 +120,93 @@ static int mail_led_set(struct led_classdev *led,
return i2c_smbus_write_word_data(ap->client, 0x10, led_bits); return i2c_smbus_write_word_data(ap->client, 0x10, led_bits);
} }
static int apanel_remove(struct i2c_client *client)
{
struct apanel *ap = i2c_get_clientdata(client);
if (device_chip[APANEL_DEV_LED] != CHIP_NONE)
led_classdev_unregister(&ap->mail_led);
input_unregister_polled_device(ap->ipdev);
input_free_polled_device(ap->ipdev);
return 0;
}
static void apanel_shutdown(struct i2c_client *client)
{
apanel_remove(client);
}
static const struct i2c_device_id apanel_id[] = {
{ "fujitsu_apanel", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, apanel_id);
static struct i2c_driver apanel_driver = {
.driver = {
.name = APANEL,
},
.probe = &apanel_probe,
.remove = &apanel_remove,
.shutdown = &apanel_shutdown,
.id_table = apanel_id,
};
static struct apanel apanel = {
.keymap = {
[0] = KEY_MAIL,
[1] = KEY_WWW,
[2] = KEY_PROG2,
[3] = KEY_PROG1,
[8] = KEY_FORWARD,
[9] = KEY_REWIND,
[10] = KEY_STOPCD,
[11] = KEY_PLAYPAUSE,
},
.mail_led = {
.name = "mail:blue",
.brightness_set_blocking = mail_led_set,
},
};
/* NB: Only one panel on the i2c. */
static int apanel_probe(struct i2c_client *client, static int apanel_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct apanel *ap; struct apanel *ap;
struct input_polled_dev *ipdev;
struct input_dev *idev; struct input_dev *idev;
u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8; u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
int i, err = -ENOMEM; int i, err;
ap = &apanel; ap = devm_kzalloc(&client->dev, sizeof(*ap), GFP_KERNEL);
if (!ap)
return -ENOMEM;
ipdev = input_allocate_polled_device(); idev = devm_input_allocate_device(&client->dev);
if (!ipdev) if (!idev)
goto out1; return -ENOMEM;
ap->ipdev = ipdev; ap->idev = idev;
ap->client = client; ap->client = client;
i2c_set_clientdata(client, ap); i2c_set_clientdata(client, ap);
err = i2c_smbus_write_word_data(client, cmd, 0); err = i2c_smbus_write_word_data(client, cmd, 0);
if (err) { if (err) {
dev_warn(&client->dev, APANEL ": smbus write error %d\n", dev_warn(&client->dev, "smbus write error %d\n", err);
err); return err;
goto out3;
} }
ipdev->poll = apanel_poll; input_set_drvdata(idev, ap);
ipdev->poll_interval = POLL_INTERVAL_DEFAULT;
ipdev->private = ap;
idev = ipdev->input;
idev->name = APANEL_NAME " buttons"; idev->name = APANEL_NAME " buttons";
idev->phys = "apanel/input0"; idev->phys = "apanel/input0";
idev->id.bustype = BUS_HOST; idev->id.bustype = BUS_HOST;
idev->dev.parent = &client->dev;
set_bit(EV_KEY, idev->evbit);
memcpy(ap->keymap, apanel_keymap, sizeof(apanel_keymap));
idev->keycode = ap->keymap; idev->keycode = ap->keymap;
idev->keycodesize = sizeof(ap->keymap[0]); idev->keycodesize = sizeof(ap->keymap[0]);
idev->keycodemax = (device_chip[APANEL_DEV_CDBTN] != CHIP_NONE) ? 12 : 4; idev->keycodemax = (device_chip[APANEL_DEV_CDBTN] != CHIP_NONE) ? 12 : 4;
set_bit(EV_KEY, idev->evbit);
for (i = 0; i < idev->keycodemax; i++) for (i = 0; i < idev->keycodemax; i++)
if (ap->keymap[i]) if (ap->keymap[i])
set_bit(ap->keymap[i], idev->keybit); set_bit(ap->keymap[i], idev->keybit);
err = input_register_polled_device(ipdev); err = input_setup_polling(idev, apanel_poll);
if (err) if (err)
goto out3; return err;
input_set_poll_interval(idev, POLL_INTERVAL_DEFAULT);
err = input_register_device(idev);
if (err)
return err;
if (device_chip[APANEL_DEV_LED] != CHIP_NONE) { if (device_chip[APANEL_DEV_LED] != CHIP_NONE) {
err = led_classdev_register(&client->dev, &ap->mail_led); ap->mail_led.name = "mail:blue";
ap->mail_led.brightness_set_blocking = mail_led_set;
err = devm_led_classdev_register(&client->dev, &ap->mail_led);
if (err) if (err)
goto out4; return err;
} }
return 0; return 0;
out4:
input_unregister_polled_device(ipdev);
out3:
input_free_polled_device(ipdev);
out1:
return err;
} }
static void apanel_shutdown(struct i2c_client *client)
{
struct apanel *ap = i2c_get_clientdata(client);
if (device_chip[APANEL_DEV_LED] != CHIP_NONE)
led_set_brightness(&ap->mail_led, LED_OFF);
}
static const struct i2c_device_id apanel_id[] = {
{ "fujitsu_apanel", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, apanel_id);
static struct i2c_driver apanel_driver = {
.driver = {
.name = APANEL,
},
.probe = apanel_probe,
.shutdown = apanel_shutdown,
.id_table = apanel_id,
};
/* Scan the system ROM for the signature "FJKEYINF" */ /* Scan the system ROM for the signature "FJKEYINF" */
static __init const void __iomem *bios_signature(const void __iomem *bios) static __init const void __iomem *bios_signature(const void __iomem *bios)
{ {
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
...@@ -123,7 +122,6 @@ ...@@ -123,7 +122,6 @@
struct bma150_data { struct bma150_data {
struct i2c_client *client; struct i2c_client *client;
struct input_polled_dev *input_polled;
struct input_dev *input; struct input_dev *input;
u8 mode; u8 mode;
}; };
...@@ -336,13 +334,16 @@ static irqreturn_t bma150_irq_thread(int irq, void *dev) ...@@ -336,13 +334,16 @@ static irqreturn_t bma150_irq_thread(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void bma150_poll(struct input_polled_dev *dev) static void bma150_poll(struct input_dev *input)
{ {
bma150_report_xyz(dev->private); struct bma150_data *bma150 = input_get_drvdata(input);
bma150_report_xyz(bma150);
} }
static int bma150_open(struct bma150_data *bma150) static int bma150_open(struct input_dev *input)
{ {
struct bma150_data *bma150 = input_get_drvdata(input);
int error; int error;
error = pm_runtime_get_sync(&bma150->client->dev); error = pm_runtime_get_sync(&bma150->client->dev);
...@@ -362,44 +363,18 @@ static int bma150_open(struct bma150_data *bma150) ...@@ -362,44 +363,18 @@ static int bma150_open(struct bma150_data *bma150)
return 0; return 0;
} }
static void bma150_close(struct bma150_data *bma150) static void bma150_close(struct input_dev *input)
{ {
struct bma150_data *bma150 = input_get_drvdata(input);
pm_runtime_put_sync(&bma150->client->dev); pm_runtime_put_sync(&bma150->client->dev);
if (bma150->mode != BMA150_MODE_SLEEP) if (bma150->mode != BMA150_MODE_SLEEP)
bma150_set_mode(bma150, BMA150_MODE_SLEEP); bma150_set_mode(bma150, BMA150_MODE_SLEEP);
} }
static int bma150_irq_open(struct input_dev *input)
{
struct bma150_data *bma150 = input_get_drvdata(input);
return bma150_open(bma150);
}
static void bma150_irq_close(struct input_dev *input)
{
struct bma150_data *bma150 = input_get_drvdata(input);
bma150_close(bma150);
}
static void bma150_poll_open(struct input_polled_dev *ipoll_dev)
{
struct bma150_data *bma150 = ipoll_dev->private;
bma150_open(bma150);
}
static void bma150_poll_close(struct input_polled_dev *ipoll_dev)
{
struct bma150_data *bma150 = ipoll_dev->private;
bma150_close(bma150);
}
static int bma150_initialize(struct bma150_data *bma150, static int bma150_initialize(struct bma150_data *bma150,
const struct bma150_cfg *cfg) const struct bma150_cfg *cfg)
{ {
int error; int error;
...@@ -439,84 +414,14 @@ static int bma150_initialize(struct bma150_data *bma150, ...@@ -439,84 +414,14 @@ static int bma150_initialize(struct bma150_data *bma150,
return bma150_set_mode(bma150, BMA150_MODE_SLEEP); return bma150_set_mode(bma150, BMA150_MODE_SLEEP);
} }
static void bma150_init_input_device(struct bma150_data *bma150,
struct input_dev *idev)
{
idev->name = BMA150_DRIVER;
idev->phys = BMA150_DRIVER "/input0";
idev->id.bustype = BUS_I2C;
idev->dev.parent = &bma150->client->dev;
idev->evbit[0] = BIT_MASK(EV_ABS);
input_set_abs_params(idev, ABS_X, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
input_set_abs_params(idev, ABS_Y, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
input_set_abs_params(idev, ABS_Z, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
}
static int bma150_register_input_device(struct bma150_data *bma150)
{
struct input_dev *idev;
int error;
idev = input_allocate_device();
if (!idev)
return -ENOMEM;
bma150_init_input_device(bma150, idev);
idev->open = bma150_irq_open;
idev->close = bma150_irq_close;
input_set_drvdata(idev, bma150);
bma150->input = idev;
error = input_register_device(idev);
if (error) {
input_free_device(idev);
return error;
}
return 0;
}
static int bma150_register_polled_device(struct bma150_data *bma150)
{
struct input_polled_dev *ipoll_dev;
int error;
ipoll_dev = input_allocate_polled_device();
if (!ipoll_dev)
return -ENOMEM;
ipoll_dev->private = bma150;
ipoll_dev->open = bma150_poll_open;
ipoll_dev->close = bma150_poll_close;
ipoll_dev->poll = bma150_poll;
ipoll_dev->poll_interval = BMA150_POLL_INTERVAL;
ipoll_dev->poll_interval_min = BMA150_POLL_MIN;
ipoll_dev->poll_interval_max = BMA150_POLL_MAX;
bma150_init_input_device(bma150, ipoll_dev->input);
bma150->input_polled = ipoll_dev;
bma150->input = ipoll_dev->input;
error = input_register_polled_device(ipoll_dev);
if (error) {
input_free_polled_device(ipoll_dev);
return error;
}
return 0;
}
static int bma150_probe(struct i2c_client *client, static int bma150_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
const struct bma150_platform_data *pdata = const struct bma150_platform_data *pdata =
dev_get_platdata(&client->dev); dev_get_platdata(&client->dev);
const struct bma150_cfg *cfg; const struct bma150_cfg *cfg;
struct bma150_data *bma150; struct bma150_data *bma150;
struct input_dev *idev;
int chip_id; int chip_id;
int error; int error;
...@@ -531,7 +436,7 @@ static int bma150_probe(struct i2c_client *client, ...@@ -531,7 +436,7 @@ static int bma150_probe(struct i2c_client *client,
return -EINVAL; return -EINVAL;
} }
bma150 = kzalloc(sizeof(struct bma150_data), GFP_KERNEL); bma150 = devm_kzalloc(&client->dev, sizeof(*bma150), GFP_KERNEL);
if (!bma150) if (!bma150)
return -ENOMEM; return -ENOMEM;
...@@ -544,7 +449,7 @@ static int bma150_probe(struct i2c_client *client, ...@@ -544,7 +449,7 @@ static int bma150_probe(struct i2c_client *client,
dev_err(&client->dev, dev_err(&client->dev,
"IRQ GPIO conf. error %d, error %d\n", "IRQ GPIO conf. error %d, error %d\n",
client->irq, error); client->irq, error);
goto err_free_mem; return error;
} }
} }
cfg = &pdata->cfg; cfg = &pdata->cfg;
...@@ -554,14 +459,42 @@ static int bma150_probe(struct i2c_client *client, ...@@ -554,14 +459,42 @@ static int bma150_probe(struct i2c_client *client,
error = bma150_initialize(bma150, cfg); error = bma150_initialize(bma150, cfg);
if (error) if (error)
goto err_free_mem; return error;
if (client->irq > 0) { idev = devm_input_allocate_device(&bma150->client->dev);
error = bma150_register_input_device(bma150); if (!idev)
return -ENOMEM;
input_set_drvdata(idev, bma150);
bma150->input = idev;
idev->name = BMA150_DRIVER;
idev->phys = BMA150_DRIVER "/input0";
idev->id.bustype = BUS_I2C;
idev->open = bma150_open;
idev->close = bma150_close;
input_set_abs_params(idev, ABS_X, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
input_set_abs_params(idev, ABS_Y, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
input_set_abs_params(idev, ABS_Z, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0);
if (client->irq <= 0) {
error = input_setup_polling(idev, bma150_poll);
if (error) if (error)
goto err_free_mem; return error;
input_set_poll_interval(idev, BMA150_POLL_INTERVAL);
input_set_min_poll_interval(idev, BMA150_POLL_MIN);
input_set_max_poll_interval(idev, BMA150_POLL_MAX);
}
error = input_register_device(idev);
if (error)
return error;
error = request_threaded_irq(client->irq, if (client->irq > 0) {
error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, bma150_irq_thread, NULL, bma150_irq_thread,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, IRQF_TRIGGER_RISING | IRQF_ONESHOT,
BMA150_DRIVER, bma150); BMA150_DRIVER, bma150);
...@@ -569,13 +502,8 @@ static int bma150_probe(struct i2c_client *client, ...@@ -569,13 +502,8 @@ static int bma150_probe(struct i2c_client *client,
dev_err(&client->dev, dev_err(&client->dev,
"irq request failed %d, error %d\n", "irq request failed %d, error %d\n",
client->irq, error); client->irq, error);
input_unregister_device(bma150->input); return error;
goto err_free_mem;
} }
} else {
error = bma150_register_polled_device(bma150);
if (error)
goto err_free_mem;
} }
i2c_set_clientdata(client, bma150); i2c_set_clientdata(client, bma150);
...@@ -583,33 +511,16 @@ static int bma150_probe(struct i2c_client *client, ...@@ -583,33 +511,16 @@ static int bma150_probe(struct i2c_client *client,
pm_runtime_enable(&client->dev); pm_runtime_enable(&client->dev);
return 0; return 0;
err_free_mem:
kfree(bma150);
return error;
} }
static int bma150_remove(struct i2c_client *client) static int bma150_remove(struct i2c_client *client)
{ {
struct bma150_data *bma150 = i2c_get_clientdata(client);
pm_runtime_disable(&client->dev); pm_runtime_disable(&client->dev);
if (client->irq > 0) {
free_irq(client->irq, bma150);
input_unregister_device(bma150->input);
} else {
input_unregister_polled_device(bma150->input_polled);
input_free_polled_device(bma150->input_polled);
}
kfree(bma150);
return 0; return 0;
} }
#ifdef CONFIG_PM static int __maybe_unused bma150_suspend(struct device *dev)
static int bma150_suspend(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client); struct bma150_data *bma150 = i2c_get_clientdata(client);
...@@ -617,14 +528,13 @@ static int bma150_suspend(struct device *dev) ...@@ -617,14 +528,13 @@ static int bma150_suspend(struct device *dev)
return bma150_set_mode(bma150, BMA150_MODE_SLEEP); return bma150_set_mode(bma150, BMA150_MODE_SLEEP);
} }
static int bma150_resume(struct device *dev) static int __maybe_unused bma150_resume(struct device *dev)
{ {
struct i2c_client *client = to_i2c_client(dev); struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client); struct bma150_data *bma150 = i2c_get_clientdata(client);
return bma150_set_mode(bma150, BMA150_MODE_NORMAL); return bma150_set_mode(bma150, BMA150_MODE_NORMAL);
} }
#endif
static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL); static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
* *
* Copyright (C) 2007-2008 Yoichi Yuasa <yuasa@linux-mips.org> * Copyright (C) 2007-2008 Yoichi Yuasa <yuasa@linux-mips.org>
*/ */
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/io.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -26,16 +27,14 @@ static const unsigned short cobalt_map[] = { ...@@ -26,16 +27,14 @@ static const unsigned short cobalt_map[] = {
}; };
struct buttons_dev { struct buttons_dev {
struct input_polled_dev *poll_dev;
unsigned short keymap[ARRAY_SIZE(cobalt_map)]; unsigned short keymap[ARRAY_SIZE(cobalt_map)];
int count[ARRAY_SIZE(cobalt_map)]; int count[ARRAY_SIZE(cobalt_map)];
void __iomem *reg; void __iomem *reg;
}; };
static void handle_buttons(struct input_polled_dev *dev) static void handle_buttons(struct input_dev *input)
{ {
struct buttons_dev *bdev = dev->private; struct buttons_dev *bdev = input_get_drvdata(input);
struct input_dev *input = dev->input;
uint32_t status; uint32_t status;
int i; int i;
...@@ -62,29 +61,33 @@ static void handle_buttons(struct input_polled_dev *dev) ...@@ -62,29 +61,33 @@ static void handle_buttons(struct input_polled_dev *dev)
static int cobalt_buttons_probe(struct platform_device *pdev) static int cobalt_buttons_probe(struct platform_device *pdev)
{ {
struct buttons_dev *bdev; struct buttons_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input; struct input_dev *input;
struct resource *res; struct resource *res;
int error, i; int error, i;
bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
poll_dev = input_allocate_polled_device(); if (!bdev)
if (!bdev || !poll_dev) { return -ENOMEM;
error = -ENOMEM;
goto err_free_mem; res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
} if (!res)
return -EBUSY;
bdev->reg = devm_ioremap(&pdev->dev, res->start, resource_size(res));
if (!bdev->reg)
return -ENOMEM;
memcpy(bdev->keymap, cobalt_map, sizeof(bdev->keymap)); memcpy(bdev->keymap, cobalt_map, sizeof(bdev->keymap));
poll_dev->private = bdev; input = devm_input_allocate_device(&pdev->dev);
poll_dev->poll = handle_buttons; if (!input)
poll_dev->poll_interval = BUTTONS_POLL_INTERVAL; return -ENOMEM;
input_set_drvdata(input, bdev);
input = poll_dev->input;
input->name = "Cobalt buttons"; input->name = "Cobalt buttons";
input->phys = "cobalt/input0"; input->phys = "cobalt/input0";
input->id.bustype = BUS_HOST; input->id.bustype = BUS_HOST;
input->dev.parent = &pdev->dev;
input->keycode = bdev->keymap; input->keycode = bdev->keymap;
input->keycodemax = ARRAY_SIZE(bdev->keymap); input->keycodemax = ARRAY_SIZE(bdev->keymap);
...@@ -96,39 +99,16 @@ static int cobalt_buttons_probe(struct platform_device *pdev) ...@@ -96,39 +99,16 @@ static int cobalt_buttons_probe(struct platform_device *pdev)
__set_bit(bdev->keymap[i], input->keybit); __set_bit(bdev->keymap[i], input->keybit);
__clear_bit(KEY_RESERVED, input->keybit); __clear_bit(KEY_RESERVED, input->keybit);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
error = -EBUSY;
goto err_free_mem;
}
bdev->poll_dev = poll_dev;
bdev->reg = ioremap(res->start, resource_size(res));
dev_set_drvdata(&pdev->dev, bdev);
error = input_register_polled_device(poll_dev); error = input_setup_polling(input, handle_buttons);
if (error) if (error)
goto err_iounmap; return error;
return 0;
err_iounmap: input_set_poll_interval(input, BUTTONS_POLL_INTERVAL);
iounmap(bdev->reg);
err_free_mem:
input_free_polled_device(poll_dev);
kfree(bdev);
return error;
}
static int cobalt_buttons_remove(struct platform_device *pdev) error = input_register_device(input);
{ if (error)
struct device *dev = &pdev->dev; return error;
struct buttons_dev *bdev = dev_get_drvdata(dev);
input_unregister_polled_device(bdev->poll_dev);
input_free_polled_device(bdev->poll_dev);
iounmap(bdev->reg);
kfree(bdev);
return 0; return 0;
} }
...@@ -141,7 +121,6 @@ MODULE_ALIAS("platform:Cobalt buttons"); ...@@ -141,7 +121,6 @@ MODULE_ALIAS("platform:Cobalt buttons");
static struct platform_driver cobalt_buttons_driver = { static struct platform_driver cobalt_buttons_driver = {
.probe = cobalt_buttons_probe, .probe = cobalt_buttons_probe,
.remove = cobalt_buttons_remove,
.driver = { .driver = {
.name = "Cobalt buttons", .name = "Cobalt buttons",
}, },
......
...@@ -17,14 +17,12 @@ ...@@ -17,14 +17,12 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
struct gpio_decoder { struct gpio_decoder {
struct input_polled_dev *poll_dev;
struct gpio_descs *input_gpios; struct gpio_descs *input_gpios;
struct device *dev; struct device *dev;
u32 axis; u32 axis;
...@@ -53,15 +51,15 @@ static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder) ...@@ -53,15 +51,15 @@ static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder)
return ret; return ret;
} }
static void gpio_decoder_poll_gpios(struct input_polled_dev *poll_dev) static void gpio_decoder_poll_gpios(struct input_dev *input)
{ {
struct gpio_decoder *decoder = poll_dev->private; struct gpio_decoder *decoder = input_get_drvdata(input);
int state; int state;
state = gpio_decoder_get_gpios_state(decoder); state = gpio_decoder_get_gpios_state(decoder);
if (state >= 0 && state != decoder->last_stable) { if (state >= 0 && state != decoder->last_stable) {
input_report_abs(poll_dev->input, decoder->axis, state); input_report_abs(input, decoder->axis, state);
input_sync(poll_dev->input); input_sync(input);
decoder->last_stable = state; decoder->last_stable = state;
} }
} }
...@@ -70,20 +68,23 @@ static int gpio_decoder_probe(struct platform_device *pdev) ...@@ -70,20 +68,23 @@ static int gpio_decoder_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct gpio_decoder *decoder; struct gpio_decoder *decoder;
struct input_polled_dev *poll_dev; struct input_dev *input;
u32 max; u32 max;
int err; int err;
decoder = devm_kzalloc(dev, sizeof(struct gpio_decoder), GFP_KERNEL); decoder = devm_kzalloc(dev, sizeof(*decoder), GFP_KERNEL);
if (!decoder) if (!decoder)
return -ENOMEM; return -ENOMEM;
decoder->dev = dev;
device_property_read_u32(dev, "linux,axis", &decoder->axis); device_property_read_u32(dev, "linux,axis", &decoder->axis);
decoder->input_gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN); decoder->input_gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN);
if (IS_ERR(decoder->input_gpios)) { if (IS_ERR(decoder->input_gpios)) {
dev_err(dev, "unable to acquire input gpios\n"); dev_err(dev, "unable to acquire input gpios\n");
return PTR_ERR(decoder->input_gpios); return PTR_ERR(decoder->input_gpios);
} }
if (decoder->input_gpios->ndescs < 2) { if (decoder->input_gpios->ndescs < 2) {
dev_err(dev, "not enough gpios found\n"); dev_err(dev, "not enough gpios found\n");
return -EINVAL; return -EINVAL;
...@@ -92,22 +93,25 @@ static int gpio_decoder_probe(struct platform_device *pdev) ...@@ -92,22 +93,25 @@ static int gpio_decoder_probe(struct platform_device *pdev)
if (device_property_read_u32(dev, "decoder-max-value", &max)) if (device_property_read_u32(dev, "decoder-max-value", &max))
max = (1U << decoder->input_gpios->ndescs) - 1; max = (1U << decoder->input_gpios->ndescs) - 1;
decoder->dev = dev; input = devm_input_allocate_device(dev);
poll_dev = devm_input_allocate_polled_device(decoder->dev); if (!input)
if (!poll_dev)
return -ENOMEM; return -ENOMEM;
poll_dev->private = decoder; input_set_drvdata(input, decoder);
poll_dev->poll = gpio_decoder_poll_gpios;
decoder->poll_dev = poll_dev;
poll_dev->input->name = pdev->name; input->name = pdev->name;
poll_dev->input->id.bustype = BUS_HOST; input->id.bustype = BUS_HOST;
input_set_abs_params(poll_dev->input, decoder->axis, 0, max, 0, 0); input_set_abs_params(input, decoder->axis, 0, max, 0, 0);
err = input_setup_polling(input, gpio_decoder_poll_gpios);
if (err) {
dev_err(dev, "failed to set up polling\n");
return err;
}
err = input_register_polled_device(poll_dev); err = input_register_device(input);
if (err) { if (err) {
dev_err(dev, "failed to register polled device\n"); dev_err(dev, "failed to register input device\n");
return err; return err;
} }
......
This diff is collapsed.
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/input/kxtj9.h> #include <linux/input/kxtj9.h>
#include <linux/input-polldev.h>
#define NAME "kxtj9" #define NAME "kxtj9"
#define G_MAX 8000 #define G_MAX 8000
...@@ -71,9 +70,6 @@ struct kxtj9_data { ...@@ -71,9 +70,6 @@ struct kxtj9_data {
struct i2c_client *client; struct i2c_client *client;
struct kxtj9_platform_data pdata; struct kxtj9_platform_data pdata;
struct input_dev *input_dev; struct input_dev *input_dev;
#ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE
struct input_polled_dev *poll_dev;
#endif
unsigned int last_poll_interval; unsigned int last_poll_interval;
u8 shift; u8 shift;
u8 ctrl_reg1; u8 ctrl_reg1;
...@@ -282,50 +278,6 @@ static void kxtj9_input_close(struct input_dev *dev) ...@@ -282,50 +278,6 @@ static void kxtj9_input_close(struct input_dev *dev)
kxtj9_disable(tj9); kxtj9_disable(tj9);
} }
static void kxtj9_init_input_device(struct kxtj9_data *tj9,
struct input_dev *input_dev)
{
__set_bit(EV_ABS, input_dev->evbit);
input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT);
input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT);
input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT);
input_dev->name = "kxtj9_accel";
input_dev->id.bustype = BUS_I2C;
input_dev->dev.parent = &tj9->client->dev;
}
static int kxtj9_setup_input_device(struct kxtj9_data *tj9)
{
struct input_dev *input_dev;
int err;
input_dev = input_allocate_device();
if (!input_dev) {
dev_err(&tj9->client->dev, "input device allocate failed\n");
return -ENOMEM;
}
tj9->input_dev = input_dev;
input_dev->open = kxtj9_input_open;
input_dev->close = kxtj9_input_close;
input_set_drvdata(input_dev, tj9);
kxtj9_init_input_device(tj9, input_dev);
err = input_register_device(tj9->input_dev);
if (err) {
dev_err(&tj9->client->dev,
"unable to register input polled device %s: %d\n",
tj9->input_dev->name, err);
input_free_device(tj9->input_dev);
return err;
}
return 0;
}
/* /*
* When IRQ mode is selected, we need to provide an interface to allow the user * When IRQ mode is selected, we need to provide an interface to allow the user
* to change the output data rate of the part. For consistency, we are using * to change the output data rate of the part. For consistency, we are using
...@@ -391,12 +343,10 @@ static struct attribute_group kxtj9_attribute_group = { ...@@ -391,12 +343,10 @@ static struct attribute_group kxtj9_attribute_group = {
.attrs = kxtj9_attributes .attrs = kxtj9_attributes
}; };
static void kxtj9_poll(struct input_dev *input)
#ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE
static void kxtj9_poll(struct input_polled_dev *dev)
{ {
struct kxtj9_data *tj9 = dev->private; struct kxtj9_data *tj9 = input_get_drvdata(input);
unsigned int poll_interval = dev->poll_interval; unsigned int poll_interval = input_get_poll_interval(input);
kxtj9_report_acceleration_data(tj9); kxtj9_report_acceleration_data(tj9);
...@@ -406,72 +356,14 @@ static void kxtj9_poll(struct input_polled_dev *dev) ...@@ -406,72 +356,14 @@ static void kxtj9_poll(struct input_polled_dev *dev)
} }
} }
static void kxtj9_polled_input_open(struct input_polled_dev *dev) static void kxtj9_platform_exit(void *data)
{
struct kxtj9_data *tj9 = dev->private;
kxtj9_enable(tj9);
}
static void kxtj9_polled_input_close(struct input_polled_dev *dev)
{
struct kxtj9_data *tj9 = dev->private;
kxtj9_disable(tj9);
}
static int kxtj9_setup_polled_device(struct kxtj9_data *tj9)
{
int err;
struct input_polled_dev *poll_dev;
poll_dev = input_allocate_polled_device();
if (!poll_dev) {
dev_err(&tj9->client->dev,
"Failed to allocate polled device\n");
return -ENOMEM;
}
tj9->poll_dev = poll_dev;
tj9->input_dev = poll_dev->input;
poll_dev->private = tj9;
poll_dev->poll = kxtj9_poll;
poll_dev->open = kxtj9_polled_input_open;
poll_dev->close = kxtj9_polled_input_close;
kxtj9_init_input_device(tj9, poll_dev->input);
err = input_register_polled_device(poll_dev);
if (err) {
dev_err(&tj9->client->dev,
"Unable to register polled device, err=%d\n", err);
input_free_polled_device(poll_dev);
return err;
}
return 0;
}
static void kxtj9_teardown_polled_device(struct kxtj9_data *tj9)
{
input_unregister_polled_device(tj9->poll_dev);
input_free_polled_device(tj9->poll_dev);
}
#else
static inline int kxtj9_setup_polled_device(struct kxtj9_data *tj9)
{ {
return -ENOSYS; struct kxtj9_data *tj9 = data;
}
static inline void kxtj9_teardown_polled_device(struct kxtj9_data *tj9) if (tj9->pdata.exit)
{ tj9->pdata.exit();
} }
#endif
static int kxtj9_verify(struct kxtj9_data *tj9) static int kxtj9_verify(struct kxtj9_data *tj9)
{ {
int retval; int retval;
...@@ -494,11 +386,12 @@ static int kxtj9_verify(struct kxtj9_data *tj9) ...@@ -494,11 +386,12 @@ static int kxtj9_verify(struct kxtj9_data *tj9)
} }
static int kxtj9_probe(struct i2c_client *client, static int kxtj9_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
const struct kxtj9_platform_data *pdata = const struct kxtj9_platform_data *pdata =
dev_get_platdata(&client->dev); dev_get_platdata(&client->dev);
struct kxtj9_data *tj9; struct kxtj9_data *tj9;
struct input_dev *input_dev;
int err; int err;
if (!i2c_check_functionality(client->adapter, if (!i2c_check_functionality(client->adapter,
...@@ -512,7 +405,7 @@ static int kxtj9_probe(struct i2c_client *client, ...@@ -512,7 +405,7 @@ static int kxtj9_probe(struct i2c_client *client,
return -EINVAL; return -EINVAL;
} }
tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL); tj9 = devm_kzalloc(&client->dev, sizeof(*tj9), GFP_KERNEL);
if (!tj9) { if (!tj9) {
dev_err(&client->dev, dev_err(&client->dev,
"failed to allocate memory for module data\n"); "failed to allocate memory for module data\n");
...@@ -525,13 +418,17 @@ static int kxtj9_probe(struct i2c_client *client, ...@@ -525,13 +418,17 @@ static int kxtj9_probe(struct i2c_client *client,
if (pdata->init) { if (pdata->init) {
err = pdata->init(); err = pdata->init();
if (err < 0) if (err < 0)
goto err_free_mem; return err;
} }
err = devm_add_action_or_reset(&client->dev, kxtj9_platform_exit, tj9);
if (err)
return err;
err = kxtj9_verify(tj9); err = kxtj9_verify(tj9);
if (err < 0) { if (err < 0) {
dev_err(&client->dev, "device not recognized\n"); dev_err(&client->dev, "device not recognized\n");
goto err_pdata_exit; return err;
} }
i2c_set_clientdata(client, tj9); i2c_set_clientdata(client, tj9);
...@@ -539,66 +436,62 @@ static int kxtj9_probe(struct i2c_client *client, ...@@ -539,66 +436,62 @@ static int kxtj9_probe(struct i2c_client *client,
tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range; tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range;
tj9->last_poll_interval = tj9->pdata.init_interval; tj9->last_poll_interval = tj9->pdata.init_interval;
input_dev = devm_input_allocate_device(&client->dev);
if (!input_dev) {
dev_err(&client->dev, "input device allocate failed\n");
return -ENOMEM;
}
input_set_drvdata(input_dev, tj9);
tj9->input_dev = input_dev;
input_dev->name = "kxtj9_accel";
input_dev->id.bustype = BUS_I2C;
input_dev->open = kxtj9_input_open;
input_dev->close = kxtj9_input_close;
input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT);
input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT);
input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT);
if (client->irq <= 0) {
err = input_setup_polling(input_dev, kxtj9_poll);
if (err)
return err;
}
err = input_register_device(input_dev);
if (err) {
dev_err(&client->dev,
"unable to register input polled device %s: %d\n",
input_dev->name, err);
return err;
}
if (client->irq) { if (client->irq) {
/* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */ /* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */
tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL; tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL;
tj9->ctrl_reg1 |= DRDYE; tj9->ctrl_reg1 |= DRDYE;
err = kxtj9_setup_input_device(tj9); err = devm_request_threaded_irq(&client->dev, client->irq,
if (err) NULL, kxtj9_isr,
goto err_pdata_exit; IRQF_TRIGGER_RISING |
IRQF_ONESHOT,
err = request_threaded_irq(client->irq, NULL, kxtj9_isr, "kxtj9-irq", tj9);
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"kxtj9-irq", tj9);
if (err) { if (err) {
dev_err(&client->dev, "request irq failed: %d\n", err); dev_err(&client->dev, "request irq failed: %d\n", err);
goto err_destroy_input; return err;
} }
err = sysfs_create_group(&client->dev.kobj, &kxtj9_attribute_group); err = devm_device_add_group(&client->dev,
&kxtj9_attribute_group);
if (err) { if (err) {
dev_err(&client->dev, "sysfs create failed: %d\n", err); dev_err(&client->dev, "sysfs create failed: %d\n", err);
goto err_free_irq; return err;
} }
} else {
err = kxtj9_setup_polled_device(tj9);
if (err)
goto err_pdata_exit;
} }
return 0;
err_free_irq:
free_irq(client->irq, tj9);
err_destroy_input:
input_unregister_device(tj9->input_dev);
err_pdata_exit:
if (tj9->pdata.exit)
tj9->pdata.exit();
err_free_mem:
kfree(tj9);
return err;
}
static int kxtj9_remove(struct i2c_client *client)
{
struct kxtj9_data *tj9 = i2c_get_clientdata(client);
if (client->irq) {
sysfs_remove_group(&client->dev.kobj, &kxtj9_attribute_group);
free_irq(client->irq, tj9);
input_unregister_device(tj9->input_dev);
} else {
kxtj9_teardown_polled_device(tj9);
}
if (tj9->pdata.exit)
tj9->pdata.exit();
kfree(tj9);
return 0; return 0;
} }
...@@ -647,7 +540,6 @@ static struct i2c_driver kxtj9_driver = { ...@@ -647,7 +540,6 @@ static struct i2c_driver kxtj9_driver = {
.pm = &kxtj9_pm_ops, .pm = &kxtj9_pm_ops,
}, },
.probe = kxtj9_probe, .probe = kxtj9_probe,
.remove = kxtj9_remove,
.id_table = kxtj9_id, .id_table = kxtj9_id,
}; };
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#define MMA8450_DRV_NAME "mma8450" #define MMA8450_DRV_NAME "mma8450"
...@@ -39,15 +39,8 @@ ...@@ -39,15 +39,8 @@
#define MMA8450_CTRL_REG1 0x38 #define MMA8450_CTRL_REG1 0x38
#define MMA8450_CTRL_REG2 0x39 #define MMA8450_CTRL_REG2 0x39
/* mma8450 status */ static int mma8450_read(struct i2c_client *c, unsigned int off)
struct mma8450 {
struct i2c_client *client;
struct input_polled_dev *idev;
};
static int mma8450_read(struct mma8450 *m, unsigned off)
{ {
struct i2c_client *c = m->client;
int ret; int ret;
ret = i2c_smbus_read_byte_data(c, off); ret = i2c_smbus_read_byte_data(c, off);
...@@ -59,9 +52,8 @@ static int mma8450_read(struct mma8450 *m, unsigned off) ...@@ -59,9 +52,8 @@ static int mma8450_read(struct mma8450 *m, unsigned off)
return ret; return ret;
} }
static int mma8450_write(struct mma8450 *m, unsigned off, u8 v) static int mma8450_write(struct i2c_client *c, unsigned int off, u8 v)
{ {
struct i2c_client *c = m->client;
int error; int error;
error = i2c_smbus_write_byte_data(c, off, v); error = i2c_smbus_write_byte_data(c, off, v);
...@@ -75,10 +67,9 @@ static int mma8450_write(struct mma8450 *m, unsigned off, u8 v) ...@@ -75,10 +67,9 @@ static int mma8450_write(struct mma8450 *m, unsigned off, u8 v)
return 0; return 0;
} }
static int mma8450_read_block(struct mma8450 *m, unsigned off, static int mma8450_read_block(struct i2c_client *c, unsigned int off,
u8 *buf, size_t size) u8 *buf, size_t size)
{ {
struct i2c_client *c = m->client;
int err; int err;
err = i2c_smbus_read_i2c_block_data(c, off, size, buf); err = i2c_smbus_read_i2c_block_data(c, off, size, buf);
...@@ -92,21 +83,21 @@ static int mma8450_read_block(struct mma8450 *m, unsigned off, ...@@ -92,21 +83,21 @@ static int mma8450_read_block(struct mma8450 *m, unsigned off,
return 0; return 0;
} }
static void mma8450_poll(struct input_polled_dev *dev) static void mma8450_poll(struct input_dev *input)
{ {
struct mma8450 *m = dev->private; struct i2c_client *c = input_get_drvdata(input);
int x, y, z; int x, y, z;
int ret; int ret;
u8 buf[6]; u8 buf[6];
ret = mma8450_read(m, MMA8450_STATUS); ret = mma8450_read(c, MMA8450_STATUS);
if (ret < 0) if (ret < 0)
return; return;
if (!(ret & MMA8450_STATUS_ZXYDR)) if (!(ret & MMA8450_STATUS_ZXYDR))
return; return;
ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf)); ret = mma8450_read_block(c, MMA8450_OUT_X_LSB, buf, sizeof(buf));
if (ret < 0) if (ret < 0)
return; return;
...@@ -114,41 +105,42 @@ static void mma8450_poll(struct input_polled_dev *dev) ...@@ -114,41 +105,42 @@ static void mma8450_poll(struct input_polled_dev *dev)
y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf); y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
z = ((int)(s8)buf[5] << 4) | (buf[4] & 0xf); z = ((int)(s8)buf[5] << 4) | (buf[4] & 0xf);
input_report_abs(dev->input, ABS_X, x); input_report_abs(input, ABS_X, x);
input_report_abs(dev->input, ABS_Y, y); input_report_abs(input, ABS_Y, y);
input_report_abs(dev->input, ABS_Z, z); input_report_abs(input, ABS_Z, z);
input_sync(dev->input); input_sync(input);
} }
/* Initialize the MMA8450 chip */ /* Initialize the MMA8450 chip */
static void mma8450_open(struct input_polled_dev *dev) static int mma8450_open(struct input_dev *input)
{ {
struct mma8450 *m = dev->private; struct i2c_client *c = input_get_drvdata(input);
int err; int err;
/* enable all events from X/Y/Z, no FIFO */ /* enable all events from X/Y/Z, no FIFO */
err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07); err = mma8450_write(c, MMA8450_XYZ_DATA_CFG, 0x07);
if (err) if (err)
return; return err;
/* /*
* Sleep mode poll rate - 50Hz * Sleep mode poll rate - 50Hz
* System output data rate - 400Hz * System output data rate - 400Hz
* Full scale selection - Active, +/- 2G * Full scale selection - Active, +/- 2G
*/ */
err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01); err = mma8450_write(c, MMA8450_CTRL_REG1, 0x01);
if (err < 0) if (err)
return; return err;
msleep(MODE_CHANGE_DELAY_MS); msleep(MODE_CHANGE_DELAY_MS);
return 0;
} }
static void mma8450_close(struct input_polled_dev *dev) static void mma8450_close(struct input_dev *input)
{ {
struct mma8450 *m = dev->private; struct i2c_client *c = input_get_drvdata(input);
mma8450_write(m, MMA8450_CTRL_REG1, 0x00); mma8450_write(c, MMA8450_CTRL_REG1, 0x00);
mma8450_write(m, MMA8450_CTRL_REG2, 0x01); mma8450_write(c, MMA8450_CTRL_REG2, 0x01);
} }
/* /*
...@@ -157,38 +149,37 @@ static void mma8450_close(struct input_polled_dev *dev) ...@@ -157,38 +149,37 @@ static void mma8450_close(struct input_polled_dev *dev)
static int mma8450_probe(struct i2c_client *c, static int mma8450_probe(struct i2c_client *c,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct input_polled_dev *idev; struct input_dev *input;
struct mma8450 *m;
int err; int err;
m = devm_kzalloc(&c->dev, sizeof(*m), GFP_KERNEL); input = devm_input_allocate_device(&c->dev);
if (!m) if (!input)
return -ENOMEM; return -ENOMEM;
idev = devm_input_allocate_polled_device(&c->dev); input_set_drvdata(input, c);
if (!idev)
return -ENOMEM; input->name = MMA8450_DRV_NAME;
input->id.bustype = BUS_I2C;
input->open = mma8450_open;
input->close = mma8450_close;
m->client = c; input_set_abs_params(input, ABS_X, -2048, 2047, 32, 32);
m->idev = idev; input_set_abs_params(input, ABS_Y, -2048, 2047, 32, 32);
input_set_abs_params(input, ABS_Z, -2048, 2047, 32, 32);
idev->private = m; err = input_setup_polling(input, mma8450_poll);
idev->input->name = MMA8450_DRV_NAME; if (err) {
idev->input->id.bustype = BUS_I2C; dev_err(&c->dev, "failed to set up polling\n");
idev->poll = mma8450_poll; return err;
idev->poll_interval = POLL_INTERVAL; }
idev->poll_interval_max = POLL_INTERVAL_MAX;
idev->open = mma8450_open;
idev->close = mma8450_close;
__set_bit(EV_ABS, idev->input->evbit); input_set_poll_interval(input, POLL_INTERVAL);
input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32); input_set_max_poll_interval(input, POLL_INTERVAL_MAX);
input_set_abs_params(idev->input, ABS_Y, -2048, 2047, 32, 32);
input_set_abs_params(idev->input, ABS_Z, -2048, 2047, 32, 32);
err = input_register_polled_device(idev); err = input_register_device(input);
if (err) { if (err) {
dev_err(&c->dev, "failed to register polled input device\n"); dev_err(&c->dev, "failed to register input device\n");
return err; return err;
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org> * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
*/ */
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/gpio.h> #include <linux/gpio.h>
...@@ -46,56 +46,42 @@ static bool rb532_button_pressed(void) ...@@ -46,56 +46,42 @@ static bool rb532_button_pressed(void)
return !val; return !val;
} }
static void rb532_button_poll(struct input_polled_dev *poll_dev) static void rb532_button_poll(struct input_dev *input)
{ {
input_report_key(poll_dev->input, RB532_BTN_KSYM, input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed());
rb532_button_pressed()); input_sync(input);
input_sync(poll_dev->input);
} }
static int rb532_button_probe(struct platform_device *pdev) static int rb532_button_probe(struct platform_device *pdev)
{ {
struct input_polled_dev *poll_dev; struct input_dev *input;
int error; int error;
poll_dev = input_allocate_polled_device(); input = devm_input_allocate_device(&pdev->dev);
if (!poll_dev) if (!input)
return -ENOMEM; return -ENOMEM;
poll_dev->poll = rb532_button_poll; input->name = "rb532 button";
poll_dev->poll_interval = RB532_BTN_RATE; input->phys = "rb532/button0";
input->id.bustype = BUS_HOST;
poll_dev->input->name = "rb532 button"; input_set_capability(input, EV_KEY, RB532_BTN_KSYM);
poll_dev->input->phys = "rb532/button0";
poll_dev->input->id.bustype = BUS_HOST;
poll_dev->input->dev.parent = &pdev->dev;
dev_set_drvdata(&pdev->dev, poll_dev); error = input_setup_polling(input, rb532_button_poll);
if (error)
input_set_capability(poll_dev->input, EV_KEY, RB532_BTN_KSYM);
error = input_register_polled_device(poll_dev);
if (error) {
input_free_polled_device(poll_dev);
return error; return error;
}
return 0; input_set_poll_interval(input, RB532_BTN_RATE);
}
static int rb532_button_remove(struct platform_device *pdev) error = input_register_device(input);
{ if (error)
struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev); return error;
input_unregister_polled_device(poll_dev);
input_free_polled_device(poll_dev);
return 0; return 0;
} }
static struct platform_driver rb532_button_driver = { static struct platform_driver rb532_button_driver = {
.probe = rb532_button_probe, .probe = rb532_button_probe,
.remove = rb532_button_remove,
.driver = { .driver = {
.name = DRV_NAME, .name = DRV_NAME,
}, },
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (C) 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de> * Copyright (C) 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*/ */
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -45,15 +45,13 @@ static const unsigned short sgi_map[] = { ...@@ -45,15 +45,13 @@ static const unsigned short sgi_map[] = {
}; };
struct buttons_dev { struct buttons_dev {
struct input_polled_dev *poll_dev;
unsigned short keymap[ARRAY_SIZE(sgi_map)]; unsigned short keymap[ARRAY_SIZE(sgi_map)];
int count[ARRAY_SIZE(sgi_map)]; int count[ARRAY_SIZE(sgi_map)];
}; };
static void handle_buttons(struct input_polled_dev *dev) static void handle_buttons(struct input_dev *input)
{ {
struct buttons_dev *bdev = dev->private; struct buttons_dev *bdev = input_get_drvdata(input);
struct input_dev *input = dev->input;
u8 status; u8 status;
int i; int i;
...@@ -80,28 +78,24 @@ static void handle_buttons(struct input_polled_dev *dev) ...@@ -80,28 +78,24 @@ static void handle_buttons(struct input_polled_dev *dev)
static int sgi_buttons_probe(struct platform_device *pdev) static int sgi_buttons_probe(struct platform_device *pdev)
{ {
struct buttons_dev *bdev; struct buttons_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input; struct input_dev *input;
int error, i; int error, i;
bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL); bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
poll_dev = input_allocate_polled_device(); if (!bdev)
if (!bdev || !poll_dev) { return -ENOMEM;
error = -ENOMEM;
goto err_free_mem; input = devm_input_allocate_device(&pdev->dev);
} if (!input)
return -ENOMEM;
memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap)); memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap));
poll_dev->private = bdev; input_set_drvdata(input, bdev);
poll_dev->poll = handle_buttons;
poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
input = poll_dev->input;
input->name = "SGI buttons"; input->name = "SGI buttons";
input->phys = "sgi/input0"; input->phys = "sgi/input0";
input->id.bustype = BUS_HOST; input->id.bustype = BUS_HOST;
input->dev.parent = &pdev->dev;
input->keycode = bdev->keymap; input->keycode = bdev->keymap;
input->keycodemax = ARRAY_SIZE(bdev->keymap); input->keycodemax = ARRAY_SIZE(bdev->keymap);
...@@ -113,35 +107,21 @@ static int sgi_buttons_probe(struct platform_device *pdev) ...@@ -113,35 +107,21 @@ static int sgi_buttons_probe(struct platform_device *pdev)
__set_bit(bdev->keymap[i], input->keybit); __set_bit(bdev->keymap[i], input->keybit);
__clear_bit(KEY_RESERVED, input->keybit); __clear_bit(KEY_RESERVED, input->keybit);
bdev->poll_dev = poll_dev; error = input_setup_polling(input, handle_buttons);
platform_set_drvdata(pdev, bdev);
error = input_register_polled_device(poll_dev);
if (error) if (error)
goto err_free_mem; return error;
return 0; input_set_poll_interval(input, BUTTONS_POLL_INTERVAL);
err_free_mem: error = input_register_device(input);
input_free_polled_device(poll_dev); if (error)
kfree(bdev); return error;
return error;
}
static int sgi_buttons_remove(struct platform_device *pdev)
{
struct buttons_dev *bdev = platform_get_drvdata(pdev);
input_unregister_polled_device(bdev->poll_dev);
input_free_polled_device(bdev->poll_dev);
kfree(bdev);
return 0; return 0;
} }
static struct platform_driver sgi_buttons_driver = { static struct platform_driver sgi_buttons_driver = {
.probe = sgi_buttons_probe, .probe = sgi_buttons_probe,
.remove = sgi_buttons_remove,
.driver = { .driver = {
.name = "sgibtns", .name = "sgibtns",
}, },
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/dmi.h> #include <linux/dmi.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/input/sparse-keymap.h> #include <linux/input/sparse-keymap.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
...@@ -1030,7 +1030,7 @@ static int __init select_keymap(void) ...@@ -1030,7 +1030,7 @@ static int __init select_keymap(void)
/* Input layer interface */ /* Input layer interface */
static struct input_polled_dev *wistron_idev; static struct input_dev *wistron_idev;
static unsigned long jiffies_last_press; static unsigned long jiffies_last_press;
static bool wifi_enabled; static bool wifi_enabled;
static bool bluetooth_enabled; static bool bluetooth_enabled;
...@@ -1114,7 +1114,7 @@ static inline void wistron_led_resume(void) ...@@ -1114,7 +1114,7 @@ static inline void wistron_led_resume(void)
static void handle_key(u8 code) static void handle_key(u8 code)
{ {
const struct key_entry *key = const struct key_entry *key =
sparse_keymap_entry_from_scancode(wistron_idev->input, code); sparse_keymap_entry_from_scancode(wistron_idev, code);
if (key) { if (key) {
switch (key->type) { switch (key->type) {
...@@ -1133,14 +1133,14 @@ static void handle_key(u8 code) ...@@ -1133,14 +1133,14 @@ static void handle_key(u8 code)
break; break;
default: default:
sparse_keymap_report_entry(wistron_idev->input, sparse_keymap_report_entry(wistron_idev, key, 1, true);
key, 1, true);
break; break;
} }
jiffies_last_press = jiffies; jiffies_last_press = jiffies;
} else } else {
printk(KERN_NOTICE printk(KERN_NOTICE
"wistron_btns: Unknown key code %02X\n", code); "wistron_btns: Unknown key code %02X\n", code);
}
} }
static void poll_bios(bool discard) static void poll_bios(bool discard)
...@@ -1158,21 +1158,23 @@ static void poll_bios(bool discard) ...@@ -1158,21 +1158,23 @@ static void poll_bios(bool discard)
} }
} }
static void wistron_flush(struct input_polled_dev *dev) static int wistron_flush(struct input_dev *dev)
{ {
/* Flush stale event queue */ /* Flush stale event queue */
poll_bios(true); poll_bios(true);
return 0;
} }
static void wistron_poll(struct input_polled_dev *dev) static void wistron_poll(struct input_dev *dev)
{ {
poll_bios(false); poll_bios(false);
/* Increase poll frequency if user is currently pressing keys (< 2s ago) */ /* Increase poll frequency if user is currently pressing keys (< 2s ago) */
if (time_before(jiffies, jiffies_last_press + 2 * HZ)) if (time_before(jiffies, jiffies_last_press + 2 * HZ))
dev->poll_interval = POLL_INTERVAL_BURST; input_set_poll_interval(dev, POLL_INTERVAL_BURST);
else else
dev->poll_interval = POLL_INTERVAL_DEFAULT; input_set_poll_interval(dev, POLL_INTERVAL_DEFAULT);
} }
static int wistron_setup_keymap(struct input_dev *dev, static int wistron_setup_keymap(struct input_dev *dev,
...@@ -1208,35 +1210,37 @@ static int wistron_setup_keymap(struct input_dev *dev, ...@@ -1208,35 +1210,37 @@ static int wistron_setup_keymap(struct input_dev *dev,
static int setup_input_dev(void) static int setup_input_dev(void)
{ {
struct input_dev *input_dev;
int error; int error;
wistron_idev = input_allocate_polled_device(); wistron_idev = input_allocate_device();
if (!wistron_idev) if (!wistron_idev)
return -ENOMEM; return -ENOMEM;
wistron_idev->name = "Wistron laptop buttons";
wistron_idev->phys = "wistron/input0";
wistron_idev->id.bustype = BUS_HOST;
wistron_idev->dev.parent = &wistron_device->dev;
wistron_idev->open = wistron_flush; wistron_idev->open = wistron_flush;
wistron_idev->poll = wistron_poll;
wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
input_dev = wistron_idev->input; error = sparse_keymap_setup(wistron_idev, keymap, wistron_setup_keymap);
input_dev->name = "Wistron laptop buttons"; if (error)
input_dev->phys = "wistron/input0"; goto err_free_dev;
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &wistron_device->dev;
error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap); error = input_setup_polling(wistron_idev, wistron_poll);
if (error) if (error)
goto err_free_dev; goto err_free_dev;
error = input_register_polled_device(wistron_idev); input_set_poll_interval(wistron_idev, POLL_INTERVAL_DEFAULT);
error = input_register_device(wistron_idev);
if (error) if (error)
goto err_free_dev; goto err_free_dev;
return 0; return 0;
err_free_dev: err_free_dev:
input_free_polled_device(wistron_idev); input_free_device(wistron_idev);
return error; return error;
} }
...@@ -1285,8 +1289,7 @@ static int wistron_probe(struct platform_device *dev) ...@@ -1285,8 +1289,7 @@ static int wistron_probe(struct platform_device *dev)
static int wistron_remove(struct platform_device *dev) static int wistron_remove(struct platform_device *dev)
{ {
wistron_led_remove(); wistron_led_remove();
input_unregister_polled_device(wistron_idev); input_unregister_device(wistron_idev);
input_free_polled_device(wistron_idev);
bios_detach(); bios_detach();
return 0; return 0;
......
...@@ -92,14 +92,14 @@ config MOUSE_PS2_SYNAPTICS_SMBUS ...@@ -92,14 +92,14 @@ config MOUSE_PS2_SYNAPTICS_SMBUS
If unsure, say Y. If unsure, say Y.
config MOUSE_PS2_CYPRESS config MOUSE_PS2_CYPRESS
bool "Cypress PS/2 mouse protocol extension" if EXPERT bool "Cypress PS/2 mouse protocol extension" if EXPERT
default y default y
depends on MOUSE_PS2 depends on MOUSE_PS2
help help
Say Y here if you have a Cypress PS/2 Trackpad connected to Say Y here if you have a Cypress PS/2 Trackpad connected to
your system. your system.
If unsure, say Y. If unsure, say Y.
config MOUSE_PS2_LIFEBOOK config MOUSE_PS2_LIFEBOOK
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT
...@@ -381,7 +381,6 @@ config MOUSE_VSXXXAA ...@@ -381,7 +381,6 @@ config MOUSE_VSXXXAA
config MOUSE_GPIO config MOUSE_GPIO
tristate "GPIO mouse" tristate "GPIO mouse"
depends on GPIOLIB || COMPILE_TEST depends on GPIOLIB || COMPILE_TEST
select INPUT_POLLDEV
help help
This driver simulates a mouse on GPIO lines of various CPUs (and some This driver simulates a mouse on GPIO lines of various CPUs (and some
other chips). other chips).
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/input-polldev.h> #include <linux/input.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/of.h> #include <linux/of.h>
...@@ -43,10 +43,9 @@ struct gpio_mouse { ...@@ -43,10 +43,9 @@ struct gpio_mouse {
* Timer function which is run every scan_ms ms when the device is opened. * Timer function which is run every scan_ms ms when the device is opened.
* The dev input variable is set to the the input_dev pointer. * The dev input variable is set to the the input_dev pointer.
*/ */
static void gpio_mouse_scan(struct input_polled_dev *dev) static void gpio_mouse_scan(struct input_dev *input)
{ {
struct gpio_mouse *gpio = dev->private; struct gpio_mouse *gpio = input_get_drvdata(input);
struct input_dev *input = dev->input;
int x, y; int x, y;
if (gpio->bleft) if (gpio->bleft)
...@@ -71,18 +70,17 @@ static int gpio_mouse_probe(struct platform_device *pdev) ...@@ -71,18 +70,17 @@ static int gpio_mouse_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct gpio_mouse *gmouse; struct gpio_mouse *gmouse;
struct input_polled_dev *input_poll;
struct input_dev *input; struct input_dev *input;
int ret; int error;
gmouse = devm_kzalloc(dev, sizeof(*gmouse), GFP_KERNEL); gmouse = devm_kzalloc(dev, sizeof(*gmouse), GFP_KERNEL);
if (!gmouse) if (!gmouse)
return -ENOMEM; return -ENOMEM;
/* Assign some default scanning time */ /* Assign some default scanning time */
ret = device_property_read_u32(dev, "scan-interval-ms", error = device_property_read_u32(dev, "scan-interval-ms",
&gmouse->scan_ms); &gmouse->scan_ms);
if (ret || gmouse->scan_ms == 0) { if (error || gmouse->scan_ms == 0) {
dev_warn(dev, "invalid scan time, set to 50 ms\n"); dev_warn(dev, "invalid scan time, set to 50 ms\n");
gmouse->scan_ms = 50; gmouse->scan_ms = 50;
} }
...@@ -112,23 +110,14 @@ static int gpio_mouse_probe(struct platform_device *pdev) ...@@ -112,23 +110,14 @@ static int gpio_mouse_probe(struct platform_device *pdev)
if (IS_ERR(gmouse->bright)) if (IS_ERR(gmouse->bright))
return PTR_ERR(gmouse->bright); return PTR_ERR(gmouse->bright);
input_poll = devm_input_allocate_polled_device(dev); input = devm_input_allocate_device(dev);
if (!input_poll) { if (!input)
dev_err(dev, "not enough memory for input device\n");
return -ENOMEM; return -ENOMEM;
}
platform_set_drvdata(pdev, input_poll);
/* set input-polldev handlers */
input_poll->private = gmouse;
input_poll->poll = gpio_mouse_scan;
input_poll->poll_interval = gmouse->scan_ms;
input = input_poll->input;
input->name = pdev->name; input->name = pdev->name;
input->id.bustype = BUS_HOST; input->id.bustype = BUS_HOST;
input->dev.parent = &pdev->dev;
input_set_drvdata(input, gmouse);
input_set_capability(input, EV_REL, REL_X); input_set_capability(input, EV_REL, REL_X);
input_set_capability(input, EV_REL, REL_Y); input_set_capability(input, EV_REL, REL_Y);
...@@ -139,10 +128,16 @@ static int gpio_mouse_probe(struct platform_device *pdev) ...@@ -139,10 +128,16 @@ static int gpio_mouse_probe(struct platform_device *pdev)
if (gmouse->bright) if (gmouse->bright)
input_set_capability(input, EV_KEY, BTN_RIGHT); input_set_capability(input, EV_KEY, BTN_RIGHT);
ret = input_register_polled_device(input_poll); error = input_setup_polling(input, gpio_mouse_scan);
if (ret) { if (error)
return error;
input_set_poll_interval(input, gmouse->scan_ms);
error = input_register_device(input);
if (error) {
dev_err(dev, "could not register input device\n"); dev_err(dev, "could not register input device\n");
return ret; return error;
} }
dev_dbg(dev, "%d ms scan time, buttons: %s%s%s\n", dev_dbg(dev, "%d ms scan time, buttons: %s%s%s\n",
......
...@@ -172,6 +172,7 @@ static const char * const smbus_pnp_ids[] = { ...@@ -172,6 +172,7 @@ static const char * const smbus_pnp_ids[] = {
"LEN0071", /* T480 */ "LEN0071", /* T480 */
"LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */ "LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
"LEN0073", /* X1 Carbon G5 (Elantech) */ "LEN0073", /* X1 Carbon G5 (Elantech) */
"LEN0091", /* X1 Carbon 6 */
"LEN0092", /* X1 Carbon 6 */ "LEN0092", /* X1 Carbon 6 */
"LEN0093", /* T480 */ "LEN0093", /* T480 */
"LEN0096", /* X280 */ "LEN0096", /* X280 */
......
...@@ -81,11 +81,6 @@ static const char * const rmi_f54_report_type_names[] = { ...@@ -81,11 +81,6 @@ static const char * const rmi_f54_report_type_names[] = {
= "Full Raw Capacitance RX Offset Removed", = "Full Raw Capacitance RX Offset Removed",
}; };
struct rmi_f54_reports {
int start;
int size;
};
struct f54_data { struct f54_data {
struct rmi_function *fn; struct rmi_function *fn;
...@@ -98,7 +93,6 @@ struct f54_data { ...@@ -98,7 +93,6 @@ struct f54_data {
enum rmi_f54_report_type report_type; enum rmi_f54_report_type report_type;
u8 *report_data; u8 *report_data;
int report_size; int report_size;
struct rmi_f54_reports standard_report[2];
bool is_busy; bool is_busy;
struct mutex status_mutex; struct mutex status_mutex;
...@@ -116,6 +110,7 @@ struct f54_data { ...@@ -116,6 +110,7 @@ struct f54_data {
struct video_device vdev; struct video_device vdev;
struct vb2_queue queue; struct vb2_queue queue;
struct mutex lock; struct mutex lock;
u32 sequence;
int input; int input;
enum rmi_f54_report_type inputs[F54_MAX_REPORT_TYPE]; enum rmi_f54_report_type inputs[F54_MAX_REPORT_TYPE];
}; };
...@@ -290,6 +285,7 @@ static int rmi_f54_queue_setup(struct vb2_queue *q, unsigned int *nbuffers, ...@@ -290,6 +285,7 @@ static int rmi_f54_queue_setup(struct vb2_queue *q, unsigned int *nbuffers,
static void rmi_f54_buffer_queue(struct vb2_buffer *vb) static void rmi_f54_buffer_queue(struct vb2_buffer *vb)
{ {
struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
struct f54_data *f54 = vb2_get_drv_priv(vb->vb2_queue); struct f54_data *f54 = vb2_get_drv_priv(vb->vb2_queue);
u16 *ptr; u16 *ptr;
enum vb2_buffer_state state; enum vb2_buffer_state state;
...@@ -298,6 +294,7 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb) ...@@ -298,6 +294,7 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb)
mutex_lock(&f54->status_mutex); mutex_lock(&f54->status_mutex);
vb2_set_plane_payload(vb, 0, 0);
reptype = rmi_f54_get_reptype(f54, f54->input); reptype = rmi_f54_get_reptype(f54, f54->input);
if (reptype == F54_REPORT_NONE) { if (reptype == F54_REPORT_NONE) {
state = VB2_BUF_STATE_ERROR; state = VB2_BUF_STATE_ERROR;
...@@ -344,14 +341,25 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb) ...@@ -344,14 +341,25 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb)
data_done: data_done:
mutex_unlock(&f54->data_mutex); mutex_unlock(&f54->data_mutex);
done: done:
vb->timestamp = ktime_get_ns();
vbuf->field = V4L2_FIELD_NONE;
vbuf->sequence = f54->sequence++;
vb2_buffer_done(vb, state); vb2_buffer_done(vb, state);
mutex_unlock(&f54->status_mutex); mutex_unlock(&f54->status_mutex);
} }
static void rmi_f54_stop_streaming(struct vb2_queue *q)
{
struct f54_data *f54 = vb2_get_drv_priv(q);
f54->sequence = 0;
}
/* V4L2 structures */ /* V4L2 structures */
static const struct vb2_ops rmi_f54_queue_ops = { static const struct vb2_ops rmi_f54_queue_ops = {
.queue_setup = rmi_f54_queue_setup, .queue_setup = rmi_f54_queue_setup,
.buf_queue = rmi_f54_buffer_queue, .buf_queue = rmi_f54_buffer_queue,
.stop_streaming = rmi_f54_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare, .wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish, .wait_finish = vb2_ops_wait_finish,
}; };
...@@ -363,7 +371,6 @@ static const struct vb2_queue rmi_f54_queue = { ...@@ -363,7 +371,6 @@ static const struct vb2_queue rmi_f54_queue = {
.ops = &rmi_f54_queue_ops, .ops = &rmi_f54_queue_ops,
.mem_ops = &vb2_vmalloc_memops, .mem_ops = &vb2_vmalloc_memops,
.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC, .timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
.min_buffers_needed = 1,
}; };
static int rmi_f54_vidioc_querycap(struct file *file, void *priv, static int rmi_f54_vidioc_querycap(struct file *file, void *priv,
...@@ -516,13 +523,10 @@ static void rmi_f54_work(struct work_struct *work) ...@@ -516,13 +523,10 @@ static void rmi_f54_work(struct work_struct *work)
struct f54_data *f54 = container_of(work, struct f54_data, work.work); struct f54_data *f54 = container_of(work, struct f54_data, work.work);
struct rmi_function *fn = f54->fn; struct rmi_function *fn = f54->fn;
u8 fifo[2]; u8 fifo[2];
struct rmi_f54_reports *report;
int report_size; int report_size;
u8 command; u8 command;
u8 *data;
int error; int error;
data = f54->report_data;
report_size = rmi_f54_get_report_size(f54); report_size = rmi_f54_get_report_size(f54);
if (report_size == 0) { if (report_size == 0) {
dev_err(&fn->dev, "Bad report size, report type=%d\n", dev_err(&fn->dev, "Bad report size, report type=%d\n",
...@@ -530,8 +534,6 @@ static void rmi_f54_work(struct work_struct *work) ...@@ -530,8 +534,6 @@ static void rmi_f54_work(struct work_struct *work)
error = -EINVAL; error = -EINVAL;
goto error; /* retry won't help */ goto error; /* retry won't help */
} }
f54->standard_report[0].size = report_size;
report = f54->standard_report;
mutex_lock(&f54->data_mutex); mutex_lock(&f54->data_mutex);
...@@ -556,28 +558,23 @@ static void rmi_f54_work(struct work_struct *work) ...@@ -556,28 +558,23 @@ static void rmi_f54_work(struct work_struct *work)
rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Get report command completed, reading data\n"); rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Get report command completed, reading data\n");
report_size = 0; fifo[0] = 0;
for (; report->size; report++) { fifo[1] = 0;
fifo[0] = report->start & 0xff; error = rmi_write_block(fn->rmi_dev,
fifo[1] = (report->start >> 8) & 0xff; fn->fd.data_base_addr + F54_FIFO_OFFSET,
error = rmi_write_block(fn->rmi_dev, fifo, sizeof(fifo));
fn->fd.data_base_addr + F54_FIFO_OFFSET, if (error) {
fifo, sizeof(fifo)); dev_err(&fn->dev, "Failed to set fifo start offset\n");
if (error) { goto abort;
dev_err(&fn->dev, "Failed to set fifo start offset\n"); }
goto abort;
}
error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr + error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr +
F54_REPORT_DATA_OFFSET, data, F54_REPORT_DATA_OFFSET, f54->report_data,
report->size); report_size);
if (error) { if (error) {
dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n", dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n",
__func__, report->size, error); __func__, report_size, error);
goto abort; goto abort;
}
data += report->size;
report_size += report->size;
} }
abort: abort:
......
...@@ -39,16 +39,16 @@ config TABLET_USB_AIPTEK ...@@ -39,16 +39,16 @@ config TABLET_USB_AIPTEK
module will be called aiptek. module will be called aiptek.
config TABLET_USB_GTCO config TABLET_USB_GTCO
tristate "GTCO CalComp/InterWrite USB Support" tristate "GTCO CalComp/InterWrite USB Support"
depends on USB && INPUT depends on USB && INPUT
help help
Say Y here if you want to use the USB version of the GTCO Say Y here if you want to use the USB version of the GTCO
CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support"
(CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
(CONFIG_INPUT_EVDEV) as well. (CONFIG_INPUT_EVDEV) as well.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called gtco. module will be called gtco.
config TABLET_USB_HANWANG config TABLET_USB_HANWANG
tristate "Hanwang Art Master III tablet support (USB)" tristate "Hanwang Art Master III tablet support (USB)"
......
...@@ -633,7 +633,7 @@ config TOUCHSCREEN_HP600 ...@@ -633,7 +633,7 @@ config TOUCHSCREEN_HP600
depends on SH_HP6XX && SH_ADC depends on SH_HP6XX && SH_ADC
help help
Say Y here if you have a HP Jornada 620/660/680/690 and want to Say Y here if you have a HP Jornada 620/660/680/690 and want to
support the built-in touchscreen. support the built-in touchscreen.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called hp680_ts_input. module will be called hp680_ts_input.
...@@ -700,7 +700,6 @@ config TOUCHSCREEN_EDT_FT5X06 ...@@ -700,7 +700,6 @@ config TOUCHSCREEN_EDT_FT5X06
config TOUCHSCREEN_RASPBERRYPI_FW config TOUCHSCREEN_RASPBERRYPI_FW
tristate "Raspberry Pi's firmware base touch screen support" tristate "Raspberry Pi's firmware base touch screen support"
depends on RASPBERRYPI_FIRMWARE || (RASPBERRYPI_FIRMWARE=n && COMPILE_TEST) depends on RASPBERRYPI_FIRMWARE || (RASPBERRYPI_FIRMWARE=n && COMPILE_TEST)
select INPUT_POLLDEV
help help
Say Y here if you have the official Raspberry Pi 7 inch screen on Say Y here if you have the official Raspberry Pi 7 inch screen on
your system. your system.
...@@ -1038,7 +1037,6 @@ config TOUCHSCREEN_TS4800 ...@@ -1038,7 +1037,6 @@ config TOUCHSCREEN_TS4800
depends on HAS_IOMEM && OF depends on HAS_IOMEM && OF
depends on SOC_IMX51 || COMPILE_TEST depends on SOC_IMX51 || COMPILE_TEST
select MFD_SYSCON select MFD_SYSCON
select INPUT_POLLDEV
help help
Say Y here if you have a touchscreen on a TS-4800 board. Say Y here if you have a touchscreen on a TS-4800 board.
...@@ -1210,7 +1208,6 @@ config TOUCHSCREEN_SUR40 ...@@ -1210,7 +1208,6 @@ config TOUCHSCREEN_SUR40
tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen" tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
depends on USB && MEDIA_USB_SUPPORT && HAS_DMA depends on USB && MEDIA_USB_SUPPORT && HAS_DMA
depends on VIDEO_V4L2 depends on VIDEO_V4L2
select INPUT_POLLDEV
select VIDEOBUF2_DMA_SG select VIDEOBUF2_DMA_SG
help help
Say Y here if you want support for the Samsung SUR40 touchscreen Say Y here if you want support for the Samsung SUR40 touchscreen
...@@ -1246,7 +1243,6 @@ config TOUCHSCREEN_SX8654 ...@@ -1246,7 +1243,6 @@ config TOUCHSCREEN_SX8654
config TOUCHSCREEN_TPS6507X config TOUCHSCREEN_TPS6507X
tristate "TPS6507x based touchscreens" tristate "TPS6507x based touchscreens"
depends on I2C depends on I2C
select INPUT_POLLDEV
help help
Say Y here if you have a TPS6507x based touchscreen Say Y here if you have a TPS6507x based touchscreen
controller. controller.
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#define AR1021_TOCUH_PKG_SIZE 5 #define AR1021_TOUCH_PKG_SIZE 5
#define AR1021_MAX_X 4095 #define AR1021_MAX_X 4095
#define AR1021_MAX_Y 4095 #define AR1021_MAX_Y 4095
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
struct ar1021_i2c { struct ar1021_i2c {
struct i2c_client *client; struct i2c_client *client;
struct input_dev *input; struct input_dev *input;
u8 data[AR1021_TOCUH_PKG_SIZE]; u8 data[AR1021_TOUCH_PKG_SIZE];
}; };
static irqreturn_t ar1021_i2c_irq(int irq, void *dev_id) static irqreturn_t ar1021_i2c_irq(int irq, void *dev_id)
......
...@@ -3156,6 +3156,8 @@ static int __maybe_unused mxt_suspend(struct device *dev) ...@@ -3156,6 +3156,8 @@ static int __maybe_unused mxt_suspend(struct device *dev)
mutex_unlock(&input_dev->mutex); mutex_unlock(&input_dev->mutex);
disable_irq(data->irq);
return 0; return 0;
} }
...@@ -3168,6 +3170,8 @@ static int __maybe_unused mxt_resume(struct device *dev) ...@@ -3168,6 +3170,8 @@ static int __maybe_unused mxt_resume(struct device *dev)
if (!input_dev) if (!input_dev)
return 0; return 0;
enable_irq(data->irq);
mutex_lock(&input_dev->mutex); mutex_lock(&input_dev->mutex);
if (input_dev->users) if (input_dev->users)
......
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h> #include <linux/gpio/consumer.h>
#include <linux/iio/consumer.h> #include <linux/iio/consumer.h>
#include <linux/iio/types.h> #include <linux/iio/types.h>
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/input/touchscreen.h> #include <linux/input/touchscreen.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <linux/regulator/consumer.h>
#define WORK_REGISTER_THRESHOLD 0x00 #define WORK_REGISTER_THRESHOLD 0x00
#define WORK_REGISTER_REPORT_RATE 0x08 #define WORK_REGISTER_REPORT_RATE 0x08
...@@ -88,6 +89,7 @@ struct edt_ft5x06_ts_data { ...@@ -88,6 +89,7 @@ struct edt_ft5x06_ts_data {
struct touchscreen_properties prop; struct touchscreen_properties prop;
u16 num_x; u16 num_x;
u16 num_y; u16 num_y;
struct regulator *vcc;
struct gpio_desc *reset_gpio; struct gpio_desc *reset_gpio;
struct gpio_desc *wake_gpio; struct gpio_desc *wake_gpio;
...@@ -1036,6 +1038,13 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) ...@@ -1036,6 +1038,13 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
} }
} }
static void edt_ft5x06_disable_regulator(void *arg)
{
struct edt_ft5x06_ts_data *data = arg;
regulator_disable(data->vcc);
}
static int edt_ft5x06_ts_probe(struct i2c_client *client, static int edt_ft5x06_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -1064,6 +1073,27 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, ...@@ -1064,6 +1073,27 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
tsdata->max_support_points = chip_data->max_support_points; tsdata->max_support_points = chip_data->max_support_points;
tsdata->vcc = devm_regulator_get(&client->dev, "vcc");
if (IS_ERR(tsdata->vcc)) {
error = PTR_ERR(tsdata->vcc);
if (error != -EPROBE_DEFER)
dev_err(&client->dev,
"failed to request regulator: %d\n", error);
return error;
}
error = regulator_enable(tsdata->vcc);
if (error < 0) {
dev_err(&client->dev, "failed to enable vcc: %d\n", error);
return error;
}
error = devm_add_action_or_reset(&client->dev,
edt_ft5x06_disable_regulator,
tsdata);
if (error)
return error;
tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev, tsdata->reset_gpio = devm_gpiod_get_optional(&client->dev,
"reset", GPIOD_OUT_HIGH); "reset", GPIOD_OUT_HIGH);
if (IS_ERR(tsdata->reset_gpio)) { if (IS_ERR(tsdata->reset_gpio)) {
......
This diff is collapsed.
...@@ -446,8 +446,7 @@ static int mms114_probe(struct i2c_client *client, ...@@ -446,8 +446,7 @@ static int mms114_probe(struct i2c_client *client,
data->client = client; data->client = client;
data->input_dev = input_dev; data->input_dev = input_dev;
/* FIXME: switch to device_get_match_data() when available */ match_data = device_get_match_data(&client->dev);
match_data = of_device_get_match_data(&client->dev);
if (!match_data) if (!match_data)
return -EINVAL; return -EINVAL;
......
...@@ -5,22 +5,73 @@ ...@@ -5,22 +5,73 @@
* Copyright (C) 2010-2011 Pixcir, Inc. * Copyright (C) 2010-2011 Pixcir, Inc.
*/ */
#include <asm/unaligned.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/module.h> #include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/input/touchscreen.h> #include <linux/input/touchscreen.h>
#include <linux/gpio.h> #include <linux/interrupt.h>
#include <linux/gpio/consumer.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/platform_data/pixcir_i2c_ts.h> #include <linux/module.h>
#include <asm/unaligned.h> #include <linux/slab.h>
#define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */ #define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */
/*
* Register map
*/
#define PIXCIR_REG_POWER_MODE 51
#define PIXCIR_REG_INT_MODE 52
/*
* Power modes:
* active: max scan speed
* idle: lower scan speed with automatic transition to active on touch
* halt: datasheet says sleep but this is more like halt as the chip
* clocks are cut and it can only be brought out of this mode
* using the RESET pin.
*/
enum pixcir_power_mode {
PIXCIR_POWER_ACTIVE,
PIXCIR_POWER_IDLE,
PIXCIR_POWER_HALT,
};
#define PIXCIR_POWER_MODE_MASK 0x03
#define PIXCIR_POWER_ALLOW_IDLE (1UL << 2)
/*
* Interrupt modes:
* periodical: interrupt is asserted periodicaly
* diff coordinates: interrupt is asserted when coordinates change
* level on touch: interrupt level asserted during touch
* pulse on touch: interrupt pulse asserted during touch
*
*/
enum pixcir_int_mode {
PIXCIR_INT_PERIODICAL,
PIXCIR_INT_DIFF_COORD,
PIXCIR_INT_LEVEL_TOUCH,
PIXCIR_INT_PULSE_TOUCH,
};
#define PIXCIR_INT_MODE_MASK 0x03
#define PIXCIR_INT_ENABLE (1UL << 3)
#define PIXCIR_INT_POL_HIGH (1UL << 2)
/**
* struct pixcir_i2c_chip_data - chip related data
* @max_fingers: Max number of fingers reported simultaneously by h/w
* @has_hw_ids: Hardware supports finger tracking IDs
*
*/
struct pixcir_i2c_chip_data {
u8 max_fingers;
bool has_hw_ids;
};
struct pixcir_i2c_ts_data { struct pixcir_i2c_ts_data {
struct i2c_client *client; struct i2c_client *client;
struct input_dev *input; struct input_dev *input;
...@@ -30,7 +81,6 @@ struct pixcir_i2c_ts_data { ...@@ -30,7 +81,6 @@ struct pixcir_i2c_ts_data {
struct gpio_desc *gpio_wake; struct gpio_desc *gpio_wake;
const struct pixcir_i2c_chip_data *chip; const struct pixcir_i2c_chip_data *chip;
struct touchscreen_properties prop; struct touchscreen_properties prop;
int max_fingers; /* Max fingers supported in this instance */
bool running; bool running;
}; };
...@@ -54,7 +104,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, ...@@ -54,7 +104,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
memset(report, 0, sizeof(struct pixcir_report_data)); memset(report, 0, sizeof(struct pixcir_report_data));
i = chip->has_hw_ids ? 1 : 0; i = chip->has_hw_ids ? 1 : 0;
readsize = 2 + tsdata->max_fingers * (4 + i); readsize = 2 + tsdata->chip->max_fingers * (4 + i);
if (readsize > sizeof(rdbuf)) if (readsize > sizeof(rdbuf))
readsize = sizeof(rdbuf); readsize = sizeof(rdbuf);
...@@ -75,8 +125,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, ...@@ -75,8 +125,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
} }
touch = rdbuf[0] & 0x7; touch = rdbuf[0] & 0x7;
if (touch > tsdata->max_fingers) if (touch > tsdata->chip->max_fingers)
touch = tsdata->max_fingers; touch = tsdata->chip->max_fingers;
report->num_touches = touch; report->num_touches = touch;
bufptr = &rdbuf[2]; bufptr = &rdbuf[2];
...@@ -192,7 +242,7 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, ...@@ -192,7 +242,7 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts,
ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE); ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s: can't read reg 0x%x : %d\n", dev_err(dev, "%s: can't read reg %d : %d\n",
__func__, PIXCIR_REG_POWER_MODE, ret); __func__, PIXCIR_REG_POWER_MODE, ret);
return ret; return ret;
} }
...@@ -205,7 +255,7 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, ...@@ -205,7 +255,7 @@ static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts,
ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret); ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s: can't write reg 0x%x : %d\n", dev_err(dev, "%s: can't write reg %d : %d\n",
__func__, PIXCIR_REG_POWER_MODE, ret); __func__, PIXCIR_REG_POWER_MODE, ret);
return ret; return ret;
} }
...@@ -231,7 +281,7 @@ static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, ...@@ -231,7 +281,7 @@ static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts,
ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s: can't read reg 0x%x : %d\n", dev_err(dev, "%s: can't read reg %d : %d\n",
__func__, PIXCIR_REG_INT_MODE, ret); __func__, PIXCIR_REG_INT_MODE, ret);
return ret; return ret;
} }
...@@ -246,7 +296,7 @@ static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, ...@@ -246,7 +296,7 @@ static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts,
ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s: can't write reg 0x%x : %d\n", dev_err(dev, "%s: can't write reg %d : %d\n",
__func__, PIXCIR_REG_INT_MODE, ret); __func__, PIXCIR_REG_INT_MODE, ret);
return ret; return ret;
} }
...@@ -264,7 +314,7 @@ static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) ...@@ -264,7 +314,7 @@ static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable)
ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s: can't read reg 0x%x : %d\n", dev_err(dev, "%s: can't read reg %d : %d\n",
__func__, PIXCIR_REG_INT_MODE, ret); __func__, PIXCIR_REG_INT_MODE, ret);
return ret; return ret;
} }
...@@ -276,7 +326,7 @@ static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) ...@@ -276,7 +326,7 @@ static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable)
ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "%s: can't write reg 0x%x : %d\n", dev_err(dev, "%s: can't write reg %d : %d\n",
__func__, PIXCIR_REG_INT_MODE, ret); __func__, PIXCIR_REG_INT_MODE, ret);
return ret; return ret;
} }
...@@ -412,31 +462,9 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev) ...@@ -412,31 +462,9 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume);
#ifdef CONFIG_OF
static const struct of_device_id pixcir_of_match[];
static int pixcir_parse_dt(struct device *dev,
struct pixcir_i2c_ts_data *tsdata)
{
tsdata->chip = of_device_get_match_data(dev);
if (!tsdata->chip)
return -EINVAL;
return 0;
}
#else
static int pixcir_parse_dt(struct device *dev,
struct pixcir_i2c_ts_data *tsdata)
{
return -EINVAL;
}
#endif
static int pixcir_i2c_ts_probe(struct i2c_client *client, static int pixcir_i2c_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
const struct pixcir_ts_platform_data *pdata =
dev_get_platdata(&client->dev);
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct pixcir_i2c_ts_data *tsdata; struct pixcir_i2c_ts_data *tsdata;
struct input_dev *input; struct input_dev *input;
...@@ -446,19 +474,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, ...@@ -446,19 +474,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
if (!tsdata) if (!tsdata)
return -ENOMEM; return -ENOMEM;
if (pdata) { tsdata->chip = device_get_match_data(dev);
tsdata->chip = &pdata->chip; if (!tsdata->chip && id)
} else if (dev->of_node) { tsdata->chip = (const void *)id->driver_data;
error = pixcir_parse_dt(dev, tsdata); if (!tsdata->chip) {
if (error) dev_err(dev, "can't locate chip data\n");
return error;
} else {
dev_err(dev, "platform data not defined\n");
return -EINVAL;
}
if (!tsdata->chip->max_fingers) {
dev_err(dev, "Invalid max_fingers in chip data\n");
return -EINVAL; return -EINVAL;
} }
...@@ -475,30 +495,17 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, ...@@ -475,30 +495,17 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
input->id.bustype = BUS_I2C; input->id.bustype = BUS_I2C;
input->open = pixcir_input_open; input->open = pixcir_input_open;
input->close = pixcir_input_close; input->close = pixcir_input_close;
input->dev.parent = dev;
if (pdata) {
input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0);
} else {
input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
touchscreen_parse_properties(input, true, &tsdata->prop);
if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
!input_abs_get_max(input, ABS_MT_POSITION_Y)) {
dev_err(dev, "Touchscreen size is not specified\n");
return -EINVAL;
}
}
tsdata->max_fingers = tsdata->chip->max_fingers; input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) { input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
tsdata->max_fingers = PIXCIR_MAX_SLOTS; touchscreen_parse_properties(input, true, &tsdata->prop);
dev_info(dev, "Limiting maximum fingers to %d\n", if (!input_abs_get_max(input, ABS_MT_POSITION_X) ||
tsdata->max_fingers); !input_abs_get_max(input, ABS_MT_POSITION_Y)) {
dev_err(dev, "Touchscreen size is not specified\n");
return -EINVAL;
} }
error = input_mt_init_slots(input, tsdata->max_fingers, error = input_mt_init_slots(input, tsdata->chip->max_fingers,
INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
if (error) { if (error) {
dev_err(dev, "Error initializing Multi-Touch slots\n"); dev_err(dev, "Error initializing Multi-Touch slots\n");
...@@ -510,7 +517,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, ...@@ -510,7 +517,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN); tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN);
if (IS_ERR(tsdata->gpio_attb)) { if (IS_ERR(tsdata->gpio_attb)) {
error = PTR_ERR(tsdata->gpio_attb); error = PTR_ERR(tsdata->gpio_attb);
dev_err(dev, "Failed to request ATTB gpio: %d\n", error); if (error != -EPROBE_DEFER)
dev_err(dev, "Failed to request ATTB gpio: %d\n",
error);
return error; return error;
} }
...@@ -518,7 +527,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, ...@@ -518,7 +527,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
if (IS_ERR(tsdata->gpio_reset)) { if (IS_ERR(tsdata->gpio_reset)) {
error = PTR_ERR(tsdata->gpio_reset); error = PTR_ERR(tsdata->gpio_reset);
dev_err(dev, "Failed to request RESET gpio: %d\n", error); if (error != -EPROBE_DEFER)
dev_err(dev, "Failed to request RESET gpio: %d\n",
error);
return error; return error;
} }
...@@ -574,14 +585,6 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, ...@@ -574,14 +585,6 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
return 0; return 0;
} }
static const struct i2c_device_id pixcir_i2c_ts_id[] = {
{ "pixcir_ts", 0 },
{ "pixcir_tangoc", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
#ifdef CONFIG_OF
static const struct pixcir_i2c_chip_data pixcir_ts_data = { static const struct pixcir_i2c_chip_data pixcir_ts_data = {
.max_fingers = 2, .max_fingers = 2,
/* no hw id support */ /* no hw id support */
...@@ -592,6 +595,14 @@ static const struct pixcir_i2c_chip_data pixcir_tangoc_data = { ...@@ -592,6 +595,14 @@ static const struct pixcir_i2c_chip_data pixcir_tangoc_data = {
.has_hw_ids = true, .has_hw_ids = true,
}; };
static const struct i2c_device_id pixcir_i2c_ts_id[] = {
{ "pixcir_ts", (unsigned long) &pixcir_ts_data },
{ "pixcir_tangoc", (unsigned long) &pixcir_tangoc_data },
{ }
};
MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id);
#ifdef CONFIG_OF
static const struct of_device_id pixcir_of_match[] = { static const struct of_device_id pixcir_of_match[] = {
{ .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data }, { .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data },
{ .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data }, { .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data },
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/input/mt.h> #include <linux/input/mt.h>
#include <linux/input-polldev.h>
#include <linux/input/touchscreen.h> #include <linux/input/touchscreen.h>
#include <soc/bcm2835/raspberrypi-firmware.h> #include <soc/bcm2835/raspberrypi-firmware.h>
...@@ -34,7 +33,7 @@ ...@@ -34,7 +33,7 @@
struct rpi_ts { struct rpi_ts {
struct platform_device *pdev; struct platform_device *pdev;
struct input_polled_dev *poll_dev; struct input_dev *input;
struct touchscreen_properties prop; struct touchscreen_properties prop;
void __iomem *fw_regs_va; void __iomem *fw_regs_va;
...@@ -57,10 +56,9 @@ struct rpi_ts_regs { ...@@ -57,10 +56,9 @@ struct rpi_ts_regs {
} point[RPI_TS_MAX_SUPPORTED_POINTS]; } point[RPI_TS_MAX_SUPPORTED_POINTS];
}; };
static void rpi_ts_poll(struct input_polled_dev *dev) static void rpi_ts_poll(struct input_dev *input)
{ {
struct input_dev *input = dev->input; struct rpi_ts *ts = input_get_drvdata(input);
struct rpi_ts *ts = dev->private;
struct rpi_ts_regs regs; struct rpi_ts_regs regs;
int modified_ids = 0; int modified_ids = 0;
long released_ids; long released_ids;
...@@ -123,10 +121,9 @@ static int rpi_ts_probe(struct platform_device *pdev) ...@@ -123,10 +121,9 @@ static int rpi_ts_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct input_polled_dev *poll_dev; struct input_dev *input;
struct device_node *fw_node; struct device_node *fw_node;
struct rpi_firmware *fw; struct rpi_firmware *fw;
struct input_dev *input;
struct rpi_ts *ts; struct rpi_ts *ts;
u32 touchbuf; u32 touchbuf;
int error; int error;
...@@ -160,7 +157,6 @@ static int rpi_ts_probe(struct platform_device *pdev) ...@@ -160,7 +157,6 @@ static int rpi_ts_probe(struct platform_device *pdev)
return error; return error;
} }
touchbuf = (u32)ts->fw_regs_phys; touchbuf = (u32)ts->fw_regs_phys;
error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF, error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF,
&touchbuf, sizeof(touchbuf)); &touchbuf, sizeof(touchbuf));
...@@ -170,19 +166,17 @@ static int rpi_ts_probe(struct platform_device *pdev) ...@@ -170,19 +166,17 @@ static int rpi_ts_probe(struct platform_device *pdev)
return error; return error;
} }
poll_dev = devm_input_allocate_polled_device(dev); input = devm_input_allocate_device(dev);
if (!poll_dev) { if (!input) {
dev_err(dev, "Failed to allocate input device\n"); dev_err(dev, "Failed to allocate input device\n");
return -ENOMEM; return -ENOMEM;
} }
ts->poll_dev = poll_dev;
input = poll_dev->input; ts->input = input;
input_set_drvdata(input, ts);
input->name = "raspberrypi-ts"; input->name = "raspberrypi-ts";
input->id.bustype = BUS_HOST; input->id.bustype = BUS_HOST;
poll_dev->poll_interval = RPI_TS_POLL_INTERVAL;
poll_dev->poll = rpi_ts_poll;
poll_dev->private = ts;
input_set_abs_params(input, ABS_MT_POSITION_X, 0, input_set_abs_params(input, ABS_MT_POSITION_X, 0,
RPI_TS_DEFAULT_WIDTH, 0, 0); RPI_TS_DEFAULT_WIDTH, 0, 0);
...@@ -197,7 +191,15 @@ static int rpi_ts_probe(struct platform_device *pdev) ...@@ -197,7 +191,15 @@ static int rpi_ts_probe(struct platform_device *pdev)
return error; return error;
} }
error = input_register_polled_device(poll_dev); error = input_setup_polling(input, rpi_ts_poll);
if (error) {
dev_err(dev, "could not set up polling mode, %d\n", error);
return error;
}
input_set_poll_interval(input, RPI_TS_POLL_INTERVAL);
error = input_register_device(input);
if (error) { if (error) {
dev_err(dev, "could not register input device, %d\n", error); dev_err(dev, "could not register input device, %d\n", error);
return error; return error;
...@@ -214,10 +216,10 @@ MODULE_DEVICE_TABLE(of, rpi_ts_match); ...@@ -214,10 +216,10 @@ MODULE_DEVICE_TABLE(of, rpi_ts_match);
static struct platform_driver rpi_ts_driver = { static struct platform_driver rpi_ts_driver = {
.driver = { .driver = {
.name = "raspberrypi-ts", .name = "raspberrypi-ts",
.of_match_table = rpi_ts_match, .of_match_table = rpi_ts_match,
}, },
.probe = rpi_ts_probe, .probe = rpi_ts_probe,
}; };
module_platform_driver(rpi_ts_driver); module_platform_driver(rpi_ts_driver);
......
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/gpio.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/gpio.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#define WACOM_CMD_QUERY0 0x04 #define WACOM_CMD_QUERY0 0x04
......
...@@ -383,6 +383,7 @@ int input_setup_polling(struct input_dev *dev, ...@@ -383,6 +383,7 @@ int input_setup_polling(struct input_dev *dev,
void input_set_poll_interval(struct input_dev *dev, unsigned int interval); void input_set_poll_interval(struct input_dev *dev, unsigned int interval);
void input_set_min_poll_interval(struct input_dev *dev, unsigned int interval); void input_set_min_poll_interval(struct input_dev *dev, unsigned int interval);
void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval); void input_set_max_poll_interval(struct input_dev *dev, unsigned int interval);
int input_get_poll_interval(struct input_dev *dev);
int __must_check input_register_handler(struct input_handler *); int __must_check input_register_handler(struct input_handler *);
void input_unregister_handler(struct input_handler *); void input_unregister_handler(struct input_handler *);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment