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:
Optional properties:
- 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):
-------------
aliases {
......@@ -220,6 +229,11 @@ firmware {
compatible = "fsl,imx8qxp-sc-rtc";
};
scu_key: scu-key {
compatible = "fsl,imx8qxp-sc-key", "fsl,imx-sc-key";
linux,keycodes = <KEY_POWER>;
};
watchdog {
compatible = "fsl,imx8qxp-sc-wdt", "fsl,imx-sc-wdt";
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:
- compatible:
ilitek,ili210x for ILI210x
ilitek,ili2117 for ILI2117
ilitek,ili251x for ILI251x
- 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
Required properties:
- 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:
- wakeup-source: See Documentation/devicetree/bindings/power/wakeup-source.txt
- mediatek,long-press-mode: Long press key shutdown setting, 1 for
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:
......
......@@ -15,7 +15,7 @@ Optional properties:
- st,onkey-pu-inactive: onkey pull up is not active
- 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).
see See Documentation/devicetree/bindings/input/keys.txt
see See Documentation/devicetree/bindings/input/input.yaml
Example:
......
......@@ -38,7 +38,7 @@ Optional properties:
Example:
ad7879@2c {
touchscreen0@2c {
compatible = "adi,ad7879-1";
reg = <0x2c>;
interrupt-parent = <&gpio1>;
......@@ -52,7 +52,7 @@ Example:
adi,conversion-interval = /bits/ 8 <255>;
};
ad7879@1 {
touchscreen1@1 {
compatible = "adi,ad7879";
spi-max-frequency = <5000000>;
reg = <1>;
......
......@@ -30,6 +30,7 @@ Required properties:
Optional properties:
- reset-gpios: GPIO specification for the RESET input
- wake-gpios: GPIO specification for the WAKE input
- vcc-supply: Regulator that supplies the touchscreen
- pinctrl-names: should be "default"
- 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)
}
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 */
static ssize_t input_dev_get_poll_interval(struct device *dev,
......
......@@ -334,7 +334,6 @@ config JOYSTICK_MAPLE
config JOYSTICK_PSXPAD_SPI
tristate "PlayStation 1/2 joypads via SPI interface"
depends on SPI
select INPUT_POLLDEV
help
Say Y here if you wish to connect PlayStation 1/2 joypads
via SPI interface.
......
......@@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/types.h>
......@@ -60,7 +59,7 @@ static const u8 PSX_CMD_ENABLE_MOTOR[] = {
struct psxpad {
struct spi_device *spi;
struct input_polled_dev *pdev;
struct input_dev *idev;
char phys[0x20];
bool motor1enable;
bool motor2enable;
......@@ -140,8 +139,7 @@ static void psxpad_set_motor_level(struct psxpad *pad,
static int psxpad_spi_play_effect(struct input_dev *idev,
void *data, struct ff_effect *effect)
{
struct input_polled_dev *pdev = input_get_drvdata(idev);
struct psxpad *pad = pdev->private;
struct psxpad *pad = input_get_drvdata(idev);
switch (effect->type) {
case FF_RUMBLE:
......@@ -158,10 +156,9 @@ static int psxpad_spi_init_ff(struct psxpad *pad)
{
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,
psxpad_spi_play_effect);
err = input_ff_create_memless(pad->idev, NULL, psxpad_spi_play_effect);
if (err) {
dev_err(&pad->spi->dev,
"input_ff_create_memless() failed: %d\n", err);
......@@ -189,24 +186,25 @@ static inline int psxpad_spi_init_ff(struct psxpad *pad)
}
#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);
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);
}
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 input_dev *input = pdev->input;
struct psxpad *pad = input_get_drvdata(input);
u8 b_rsp3, b_rsp4;
int err;
......@@ -284,7 +282,6 @@ static void psxpad_spi_poll(struct input_polled_dev *pdev)
static int psxpad_spi_probe(struct spi_device *spi)
{
struct psxpad *pad;
struct input_polled_dev *pdev;
struct input_dev *idev;
int err;
......@@ -292,31 +289,26 @@ static int psxpad_spi_probe(struct spi_device *spi)
if (!pad)
return -ENOMEM;
pdev = input_allocate_polled_device();
if (!pdev) {
idev = devm_input_allocate_device(&spi->dev);
if (!idev) {
dev_err(&spi->dev, "failed to allocate input device\n");
return -ENOMEM;
}
/* input poll device settings */
pad->pdev = pdev;
pad->idev = idev;
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 */
idev = pdev->input;
input_set_drvdata(idev, pad);
idev->name = "PlayStation 1/2 joypad";
snprintf(pad->phys, sizeof(pad->phys), "%s/input", dev_name(&spi->dev));
idev->id.bustype = BUS_SPI;
idev->open = psxpad_spi_poll_open;
idev->close = psxpad_spi_poll_close;
/* key/value map settings */
input_set_abs_params(idev, ABS_X, 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)
/* pad settings */
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 */
err = input_register_polled_device(pdev);
err = input_register_device(idev);
if (err) {
dev_err(&spi->dev,
"failed to register input poll device: %d\n", err);
"failed to register input device: %d\n", err);
return err;
}
......
......@@ -16,7 +16,6 @@ if INPUT_KEYBOARD
config KEYBOARD_ADC
tristate "ADC Ladder Buttons"
depends on IIO
select INPUT_POLLDEV
help
This driver implements support for buttons connected
to an ADC using a resistor ladder.
......@@ -168,14 +167,14 @@ config KEYBOARD_QT1050
the module will be called qt1050
config KEYBOARD_QT1070
tristate "Atmel AT42QT1070 Touch Sensor Chip"
depends on I2C
help
Say Y here if you want to use Atmel AT42QT1070 QTouch
Sensor chip as input device.
tristate "Atmel AT42QT1070 Touch Sensor Chip"
depends on I2C
help
Say Y here if you want to use Atmel AT42QT1070 QTouch
Sensor chip as input device.
To compile this driver as a module, choose M here:
the module will be called qt1070
To compile this driver as a module, choose M here:
the module will be called qt1070
config KEYBOARD_QT2160
tristate "Atmel AT42QT2160 Touch Sensor Chip"
......@@ -191,7 +190,6 @@ config KEYBOARD_CLPS711X
tristate "CLPS711X Keypad support"
depends on OF_GPIO && (ARCH_CLPS711X || COMPILE_TEST)
select INPUT_MATRIXKMAP
select INPUT_POLLDEV
help
Say Y here to enable the matrix keypad on the Cirrus Logic
CLPS711X CPUs.
......@@ -250,7 +248,6 @@ config KEYBOARD_GPIO
config KEYBOARD_GPIO_POLLED
tristate "Polled GPIO buttons"
depends on GPIOLIB
select INPUT_POLLDEV
help
This driver implements support for buttons connected
to GPIO pins that are not capable of generating interrupts.
......@@ -342,7 +339,6 @@ config KEYBOARD_HIL
config KEYBOARD_HP6XX
tristate "HP Jornada 6xx keyboard"
depends on SH_HP6XX
select INPUT_POLLDEV
help
Say Y here if you have a HP Jornada 620/660/680/690 and want to
support the built-in keyboard.
......@@ -469,6 +465,16 @@ config KEYBOARD_IMX
To compile this driver as a module, choose M here: the
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
tristate "Newton keyboard"
select SERIO
......
......@@ -29,6 +29,7 @@ obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o
obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o
obj-$(CONFIG_KEYBOARD_IPAQ_MICRO) += ipaq-micro-keys.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_HP7XX) += jornada720_kbd.o
obj-$(CONFIG_KEYBOARD_LKKBD) += lkkbd.o
......
......@@ -9,7 +9,6 @@
#include <linux/iio/consumer.h>
#include <linux/iio/types.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
......@@ -30,9 +29,9 @@ struct adc_keys_state {
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;
u32 diff, closest = 0xffffffff;
int keycode = 0;
......@@ -55,12 +54,12 @@ static void adc_keys_poll(struct input_polled_dev *dev)
keycode = 0;
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)
input_report_key(dev->input, keycode, 1);
input_report_key(input, keycode, 1);
input_sync(dev->input);
input_sync(input);
st->last_key = keycode;
}
......@@ -108,7 +107,6 @@ static int adc_keys_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct adc_keys_state *st;
struct input_polled_dev *poll_dev;
struct input_dev *input;
enum iio_chan_type type;
int i, value;
......@@ -145,19 +143,13 @@ static int adc_keys_probe(struct platform_device *pdev)
if (error)
return error;
poll_dev = devm_input_allocate_polled_device(dev);
if (!poll_dev) {
input = devm_input_allocate_device(dev);
if (!input) {
dev_err(dev, "failed to allocate input device\n");
return -ENOMEM;
}
if (!device_property_read_u32(dev, "poll-interval", &value))
poll_dev->poll_interval = value;
poll_dev->poll = adc_keys_poll;
poll_dev->private = st;
input = poll_dev->input;
input_set_drvdata(input, st);
input->name = pdev->name;
input->phys = "adc-keys/input0";
......@@ -174,7 +166,17 @@ static int adc_keys_probe(struct platform_device *pdev)
if (device_property_read_bool(dev, "autorepeat"))
__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) {
dev_err(dev, "Unable to register input device: %d\n", error);
return error;
......
......@@ -857,70 +857,35 @@ static void adp5589_report_switch_state(struct adp5589_kpad *kpad)
input_sync(kpad->input);
}
static int adp5589_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int adp5589_keypad_add(struct adp5589_kpad *kpad, unsigned int revid)
{
struct adp5589_kpad *kpad;
struct i2c_client *client = kpad->client;
const struct adp5589_kpad_platform_data *pdata =
dev_get_platdata(&client->dev);
struct input_dev *input;
unsigned int revid;
int ret, i;
unsigned int i;
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) &&
(pdata->keypad_en_mask >> kpad->var->col_shift)) ||
!pdata->keymap) {
dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
if (pdata->keymapsize != kpad->var->keymapsize) {
dev_err(&client->dev, "invalid keymapsize\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
if (!pdata->gpimap && pdata->gpimapsize) {
dev_err(&client->dev, "invalid gpimap from pdata\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
if (pdata->gpimapsize > kpad->var->gpimapsize_max) {
dev_err(&client->dev, "invalid gpimapsize\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
for (i = 0; i < pdata->gpimapsize; i++) {
......@@ -929,41 +894,27 @@ static int adp5589_probe(struct i2c_client *client,
if (pin < kpad->var->gpi_pin_base ||
pin > kpad->var->gpi_pin_end) {
dev_err(&client->dev, "invalid gpi pin data\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
if ((1 << (pin - kpad->var->gpi_pin_row_base)) &
pdata->keypad_en_mask) {
dev_err(&client->dev, "invalid gpi row/col data\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
}
if (!client->irq) {
dev_err(&client->dev, "no IRQ?\n");
error = -EINVAL;
goto err_free_mem;
return -EINVAL;
}
input = input_allocate_device();
if (!input) {
error = -ENOMEM;
goto err_free_mem;
}
if (!input)
return -ENOMEM;
kpad->client = client;
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->phys = "adp5589-keys/input0";
input->dev.parent = &client->dev;
......@@ -1015,30 +966,99 @@ static int adp5589_probe(struct i2c_client *client,
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);
if (error)
goto err_free_irq;
goto err_keypad_remove;
if (kpad->gpimapsize)
adp5589_report_switch_state(kpad);
error = adp5589_gpio_add(kpad);
if (error)
goto err_free_irq;
goto err_keypad_remove;
device_init_wakeup(&client->dev, 1);
i2c_set_clientdata(client, kpad);
dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
return 0;
err_free_irq:
free_irq(client->irq, kpad);
err_unreg_dev:
input_unregister_device(input);
input = NULL;
err_free_input:
input_free_device(input);
err_keypad_remove:
adp5589_keypad_remove(kpad);
err_free_mem:
kfree(kpad);
......@@ -1050,8 +1070,7 @@ static int adp5589_remove(struct i2c_client *client)
struct adp5589_kpad *kpad = i2c_get_clientdata(client);
adp5589_write(client, kpad->var->reg(ADP5589_GENERAL_CFG), 0);
free_irq(client->irq, kpad);
input_unregister_device(kpad->input);
adp5589_keypad_remove(kpad);
adp5589_gpio_remove(kpad);
kfree(kpad);
......@@ -1064,6 +1083,9 @@ static int adp5589_suspend(struct device *dev)
struct adp5589_kpad *kpad = dev_get_drvdata(dev);
struct i2c_client *client = kpad->client;
if (!kpad->input)
return 0;
disable_irq(client->irq);
if (device_may_wakeup(&client->dev))
......@@ -1077,6 +1099,9 @@ static int adp5589_resume(struct device *dev)
struct adp5589_kpad *kpad = dev_get_drvdata(dev);
struct i2c_client *client = kpad->client;
if (!kpad->input)
return 0;
if (device_may_wakeup(&client->dev))
disable_irq_wake(client->irq);
......
......@@ -6,7 +6,6 @@
*/
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
......@@ -30,10 +29,10 @@ struct clps711x_keypad_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;
struct clps711x_keypad_data *priv = dev->private;
const unsigned short *keycodes = input->keycode;
struct clps711x_keypad_data *priv = input_get_drvdata(input);
bool sync = false;
int col, row;
......@@ -61,14 +60,14 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev)
if (state) {
set_bit(col, data->last_state);
input_event(dev->input, EV_MSC,
MSC_SCAN, code);
input_event(input,
EV_MSC, MSC_SCAN, code);
} else {
clear_bit(col, data->last_state);
}
if (keycodes[code])
input_report_key(dev->input,
input_report_key(input,
keycodes[code], state);
sync = true;
}
......@@ -80,7 +79,7 @@ static void clps711x_keypad_poll(struct input_polled_dev *dev)
}
if (sync)
input_sync(dev->input);
input_sync(input);
}
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 device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct input_polled_dev *poll_dev;
struct input_dev *input;
u32 poll_interval;
int i, err;
......@@ -125,53 +124,43 @@ static int clps711x_keypad_probe(struct platform_device *pdev)
if (err)
return err;
poll_dev = input_allocate_polled_device();
if (!poll_dev)
input = devm_input_allocate_device(dev);
if (!input)
return -ENOMEM;
poll_dev->private = priv;
poll_dev->poll = clps711x_keypad_poll;
poll_dev->poll_interval = poll_interval;
poll_dev->input->name = pdev->name;
poll_dev->input->dev.parent = dev;
poll_dev->input->id.bustype = BUS_HOST;
poll_dev->input->id.vendor = 0x0001;
poll_dev->input->id.product = 0x0001;
poll_dev->input->id.version = 0x0100;
input_set_drvdata(input, priv);
input->name = pdev->name;
input->dev.parent = dev;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
err = matrix_keypad_build_keymap(NULL, NULL, priv->row_count,
CLPS711X_KEYPAD_COL_COUNT,
NULL, poll_dev->input);
NULL, input);
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"))
__set_bit(EV_REP, poll_dev->input->evbit);
platform_set_drvdata(pdev, poll_dev);
__set_bit(EV_REP, input->evbit);
/* Set all columns to low */
regmap_update_bits(priv->syscon, SYSCON_OFFSET, SYSCON1_KBDSCAN_MASK,
SYSCON1_KBDSCAN(1));
err = input_register_polled_device(poll_dev);
if (err)
goto out_err;
return 0;
out_err:
input_free_polled_device(poll_dev);
return err;
}
err = input_setup_polling(input, clps711x_keypad_poll);
if (err)
return err;
static int clps711x_keypad_remove(struct platform_device *pdev)
{
struct input_polled_dev *poll_dev = platform_get_drvdata(pdev);
input_set_poll_interval(input, poll_interval);
input_unregister_polled_device(poll_dev);
input_free_polled_device(poll_dev);
err = input_register_device(input);
if (err)
return err;
return 0;
}
......@@ -188,7 +177,6 @@ static struct platform_driver clps711x_keypad_driver = {
.of_match_table = clps711x_keypad_of_match,
},
.probe = clps711x_keypad_probe,
.remove = clps711x_keypad_remove,
};
module_platform_driver(clps711x_keypad_driver);
......
......@@ -494,10 +494,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
spin_lock_init(&bdata->lock);
if (child) {
bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev, NULL,
child,
GPIOD_IN,
desc);
bdata->gpiod = devm_fwnode_gpiod_get(dev, child,
NULL, GPIOD_IN, desc);
if (IS_ERR(bdata->gpiod)) {
error = PTR_ERR(bdata->gpiod);
if (error == -ENOENT) {
......
......@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
......@@ -34,7 +33,7 @@ struct gpio_keys_button_data {
};
struct gpio_keys_polled_dev {
struct input_polled_dev *poll_dev;
struct input_dev *input;
struct device *dev;
const struct gpio_keys_platform_data *pdata;
unsigned long rel_axis_seen[BITS_TO_LONGS(REL_CNT)];
......@@ -42,12 +41,11 @@ struct gpio_keys_polled_dev {
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,
int state)
{
struct gpio_keys_polled_dev *bdev = dev->private;
struct input_dev *input = dev->input;
struct gpio_keys_polled_dev *bdev = input_get_drvdata(input);
unsigned int type = button->type ?: EV_KEY;
if (type == EV_REL) {
......@@ -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,
struct gpio_keys_button_data *bdata)
{
......@@ -74,10 +72,10 @@ static void gpio_keys_polled_check_state(struct input_polled_dev *dev,
state = gpiod_get_value_cansleep(bdata->gpiod);
if (state < 0) {
dev_err(dev->input->dev.parent,
dev_err(input->dev.parent,
"failed to get gpio state: %d\n", state);
} else {
gpio_keys_button_event(dev, button, state);
gpio_keys_button_event(input, button, state);
if (state != bdata->last_state) {
bdata->count = 0;
......@@ -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;
struct input_dev *input = dev->input;
int i;
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)
if (bdata->count < bdata->threshold) {
bdata->count++;
gpio_keys_button_event(dev, &pdata->buttons[i],
gpio_keys_button_event(input, &pdata->buttons[i],
bdata->last_state);
} else {
gpio_keys_polled_check_state(dev, &pdata->buttons[i],
gpio_keys_polled_check_state(input, &pdata->buttons[i],
bdata);
}
}
......@@ -122,18 +119,20 @@ static void gpio_keys_polled_poll(struct input_polled_dev *dev)
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;
if (pdata->enable)
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;
if (pdata->disable)
......@@ -232,7 +231,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
struct fwnode_handle *child = NULL;
const struct gpio_keys_platform_data *pdata = dev_get_platdata(dev);
struct gpio_keys_polled_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input;
int error;
int i;
......@@ -255,19 +253,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return -ENOMEM;
}
poll_dev = devm_input_allocate_polled_device(dev);
if (!poll_dev) {
dev_err(dev, "no memory for polled device\n");
input = devm_input_allocate_device(dev);
if (!input) {
dev_err(dev, "no memory for input device\n");
return -ENOMEM;
}
poll_dev->private = 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_set_drvdata(input, bdev);
input->name = pdata->name ?: pdev->name;
input->phys = DRV_NAME"/input0";
......@@ -277,6 +269,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
input->id.product = 0x0001;
input->id.version = 0x0100;
input->open = gpio_keys_polled_open;
input->close = gpio_keys_polled_close;
__set_bit(EV_KEY, input->evbit);
if (pdata->rep)
__set_bit(EV_REP, input->evbit);
......@@ -300,10 +295,9 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return -EINVAL;
}
bdata->gpiod = devm_fwnode_get_gpiod_from_child(dev,
NULL, child,
GPIOD_IN,
button->desc);
bdata->gpiod = devm_fwnode_gpiod_get(dev, child,
NULL, GPIOD_IN,
button->desc);
if (IS_ERR(bdata->gpiod)) {
error = PTR_ERR(bdata->gpiod);
if (error != -EPROBE_DEFER)
......@@ -353,11 +347,19 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
fwnode_handle_put(child);
bdev->poll_dev = poll_dev;
bdev->input = input;
bdev->dev = dev;
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) {
dev_err(dev, "unable to register polled device, err=%d\n",
error);
......@@ -366,7 +368,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
/* report initial state of the buttons */
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]);
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 @@
#include <linux/device.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
......@@ -64,7 +63,7 @@ static const unsigned short jornada_scancodes[] = {
#define JORNADA_SCAN_SIZE 18
struct jornadakbd {
struct input_polled_dev *poll_dev;
struct input_dev *input;
unsigned short keymap[ARRAY_SIZE(jornada_scancodes)];
unsigned char length;
unsigned char old_scan[JORNADA_SCAN_SIZE];
......@@ -73,7 +72,7 @@ struct 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 int sync_me = 0;
unsigned int i, j;
......@@ -167,9 +166,9 @@ static void jornada_scan_keyb(unsigned char *s)
*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_parse_kbd(jornadakbd);
......@@ -179,7 +178,6 @@ static void jornadakbd680_poll(struct input_polled_dev *dev)
static int jornada680kbd_probe(struct platform_device *pdev)
{
struct jornadakbd *jornadakbd;
struct input_polled_dev *poll_dev;
struct input_dev *input_dev;
int i, error;
......@@ -188,29 +186,24 @@ static int jornada680kbd_probe(struct platform_device *pdev)
if (!jornadakbd)
return -ENOMEM;
poll_dev = devm_input_allocate_polled_device(&pdev->dev);
if (!poll_dev) {
dev_err(&pdev->dev, "failed to allocate polled input device\n");
input_dev = devm_input_allocate_device(&pdev->dev);
if (!input_dev) {
dev_err(&pdev->dev, "failed to allocate input device\n");
return -ENOMEM;
}
jornadakbd->poll_dev = poll_dev;
jornadakbd->input = input_dev;
memcpy(jornadakbd->keymap, jornada_scancodes,
sizeof(jornadakbd->keymap));
poll_dev->private = jornadakbd;
poll_dev->poll = jornadakbd680_poll;
poll_dev->poll_interval = 50; /* msec */
input_dev = poll_dev->input;
input_set_drvdata(input_dev, jornadakbd);
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
input_dev->name = "HP Jornada 680 keyboard";
input_dev->phys = "jornadakbd/input0";
input_dev->keycode = jornadakbd->keymap;
input_dev->keycodesize = sizeof(unsigned short);
input_dev->keycodemax = ARRAY_SIZE(jornada_scancodes);
input_dev->dev.parent = &pdev->dev;
input_dev->id.bustype = BUS_HOST;
for (i = 0; i < 128; i++)
......@@ -220,9 +213,17 @@ static int jornada680kbd_probe(struct platform_device *pdev)
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) {
dev_err(&pdev->dev, "failed to register polled input device\n");
dev_err(&pdev->dev, "failed to register input device\n");
return error;
}
......
......@@ -54,6 +54,9 @@
/* MPR121 has 12 keys */
#define MPR121_MAX_KEY_COUNT 12
#define MPR121_MIN_POLL_INTERVAL 10
#define MPR121_MAX_POLL_INTERVAL 200
struct mpr121_touchkey {
struct i2c_client *client;
struct input_dev *input_dev;
......@@ -115,11 +118,11 @@ static struct regulator *mpr121_vdd_supply_init(struct device *dev)
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 i2c_client *client = mpr121->client;
struct mpr121_touchkey *mpr121 = input_get_drvdata(dev);
struct input_dev *input = mpr121->input_dev;
struct i2c_client *client = mpr121->client;
unsigned long bit_changed;
unsigned int key_num;
int reg;
......@@ -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);
if (reg < 0) {
dev_err(&client->dev, "i2c read error [%d]\n", reg);
goto out;
return;
}
reg <<= 8;
reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR);
if (reg < 0) {
dev_err(&client->dev, "i2c read error [%d]\n", reg);
goto out;
return;
}
reg &= TOUCH_STATUS_MASK;
......@@ -155,8 +158,14 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
}
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;
}
......@@ -229,14 +238,10 @@ static int mpr_touchkey_probe(struct i2c_client *client,
int vdd_uv;
struct mpr121_touchkey *mpr121;
struct input_dev *input_dev;
u32 poll_interval = 0;
int error;
int i;
if (!client->irq) {
dev_err(dev, "irq number should not be zero\n");
return -EINVAL;
}
vdd_supply = mpr121_vdd_supply_init(dev);
if (IS_ERR(vdd_supply))
return PTR_ERR(vdd_supply);
......@@ -274,6 +279,7 @@ static int mpr_touchkey_probe(struct i2c_client *client,
if (device_property_read_bool(dev, "autorepeat"))
__set_bit(EV_REP, input_dev->evbit);
input_set_capability(input_dev, EV_MSC, MSC_SCAN);
input_set_drvdata(input_dev, mpr121);
input_dev->keycode = mpr121->keycodes;
input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
......@@ -288,13 +294,40 @@ static int mpr_touchkey_probe(struct i2c_client *client,
return error;
}
error = devm_request_threaded_irq(dev, client->irq, NULL,
mpr_touchkey_interrupt,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
dev->driver->name, mpr121);
if (error) {
dev_err(dev, "Failed to register interrupt\n");
return error;
device_property_read_u32(dev, "poll-interval", &poll_interval);
if (client->irq) {
error = devm_request_threaded_irq(dev, client->irq, NULL,
mpr_touchkey_interrupt,
IRQF_TRIGGER_FALLING |
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);
......
......@@ -100,7 +100,6 @@ config INPUT_ATMEL_CAPTOUCH
config INPUT_BMA150
tristate "BMA150/SMB380 acceleration sensor support"
depends on I2C
select INPUT_POLLDEV
help
Say Y here if you have Bosch Sensortec's BMA150 or SMB380
acceleration sensor hooked to an I2C bus.
......@@ -246,7 +245,6 @@ config INPUT_MC13783_PWRBUTTON
config INPUT_MMA8450
tristate "MMA8450 - Freescale's 3-Axis, 8/12-bit Digital Accelerometer"
depends on I2C
select INPUT_POLLDEV
help
Say Y here if you want to support Freescale's MMA8450 Accelerometer
through I2C interface.
......@@ -257,7 +255,6 @@ config INPUT_MMA8450
config INPUT_APANEL
tristate "Fujitsu Lifebook Application Panel buttons"
depends on X86 && I2C && LEDS_CLASS
select INPUT_POLLDEV
select CHECK_SIGNATURE
help
Say Y here for support of the Application Panel buttons, used on
......@@ -291,7 +288,6 @@ config INPUT_GPIO_BEEPER
config INPUT_GPIO_DECODER
tristate "Polled GPIO Decoder Input driver"
depends on GPIOLIB || COMPILE_TEST
select INPUT_POLLDEV
help
Say Y here if you want driver to read status of multiple GPIO
lines and report the encoded value as an absolute integer to
......@@ -327,7 +323,6 @@ config INPUT_IXP4XX_BEEPER
config INPUT_COBALT_BTNS
tristate "Cobalt button interface"
depends on MIPS_COBALT
select INPUT_POLLDEV
help
Say Y here if you want to support MIPS Cobalt button interface.
......@@ -347,7 +342,6 @@ config INPUT_CPCAP_PWRBUTTON
config INPUT_WISTRON_BTNS
tristate "x86 Wistron laptop button interface"
depends on X86_32
select INPUT_POLLDEV
select INPUT_SPARSEKMAP
select NEW_LEDS
select LEDS_CLASS
......@@ -410,13 +404,6 @@ config INPUT_KXTJ9
To compile this driver as a module, choose M here: the module will
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
tristate "Griffin PowerMate and Contour Jog support"
depends on USB_ARCH_HAS_HCD
......@@ -546,7 +533,6 @@ config INPUT_UINPUT
config INPUT_SGI_BTNS
tristate "SGI Indy/O2 volume button interface"
depends on SGI_IP22 || SGI_IP32
select INPUT_POLLDEV
help
Say Y here if you want to support SGI Indy/O2 volume button interface.
......@@ -637,7 +623,6 @@ config INPUT_RB532_BUTTON
tristate "Mikrotik Routerboard 532 button interface"
depends on MIKROTIK_RB532
depends on GPIOLIB
select INPUT_POLLDEV
help
Say Y here if you want support for the S1 button built into
Mikrotik's Routerboard 532.
......
......@@ -17,7 +17,7 @@
#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/input-polldev.h>
#include <linux/input.h>
#include <linux/i2c.h>
#include <linux/leds.h>
......@@ -51,19 +51,28 @@ static enum apanel_chip device_chip[APANEL_DEV_MAX];
#define MAX_PANEL_KEYS 12
struct apanel {
struct input_polled_dev *ipdev;
struct input_dev *idev;
struct i2c_client *client;
unsigned short keymap[MAX_PANEL_KEYS];
u16 nkeys;
u16 nkeys;
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)
{
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_sync(input);
......@@ -79,10 +88,9 @@ static void report_key(struct input_dev *input, unsigned keycode)
* CD keys:
* 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 input_dev *idev = ipdev->input;
struct apanel *ap = input_get_drvdata(idev);
u8 cmd = device_chip[APANEL_DEV_APPBTN] == CHIP_OZ992C ? 0 : 8;
s32 data;
int i;
......@@ -112,126 +120,93 @@ static int mail_led_set(struct led_classdev *led,
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,
const struct i2c_device_id *id)
{
struct apanel *ap;
struct input_polled_dev *ipdev;
struct input_dev *idev;
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();
if (!ipdev)
goto out1;
idev = devm_input_allocate_device(&client->dev);
if (!idev)
return -ENOMEM;
ap->ipdev = ipdev;
ap->idev = idev;
ap->client = client;
i2c_set_clientdata(client, ap);
err = i2c_smbus_write_word_data(client, cmd, 0);
if (err) {
dev_warn(&client->dev, APANEL ": smbus write error %d\n",
err);
goto out3;
dev_warn(&client->dev, "smbus write error %d\n", err);
return err;
}
ipdev->poll = apanel_poll;
ipdev->poll_interval = POLL_INTERVAL_DEFAULT;
ipdev->private = ap;
input_set_drvdata(idev, ap);
idev = ipdev->input;
idev->name = APANEL_NAME " buttons";
idev->phys = "apanel/input0";
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->keycodesize = sizeof(ap->keymap[0]);
idev->keycodemax = (device_chip[APANEL_DEV_CDBTN] != CHIP_NONE) ? 12 : 4;
set_bit(EV_KEY, idev->evbit);
for (i = 0; i < idev->keycodemax; i++)
if (ap->keymap[i])
set_bit(ap->keymap[i], idev->keybit);
err = input_register_polled_device(ipdev);
err = input_setup_polling(idev, apanel_poll);
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) {
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)
goto out4;
return err;
}
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" */
static __init const void __iomem *bios_signature(const void __iomem *bios)
{
......
......@@ -14,7 +14,6 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
......@@ -123,7 +122,6 @@
struct bma150_data {
struct i2c_client *client;
struct input_polled_dev *input_polled;
struct input_dev *input;
u8 mode;
};
......@@ -336,13 +334,16 @@ static irqreturn_t bma150_irq_thread(int irq, void *dev)
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;
error = pm_runtime_get_sync(&bma150->client->dev);
......@@ -362,44 +363,18 @@ static int bma150_open(struct bma150_data *bma150)
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);
if (bma150->mode != 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,
const struct bma150_cfg *cfg)
const struct bma150_cfg *cfg)
{
int error;
......@@ -439,84 +414,14 @@ static int bma150_initialize(struct bma150_data *bma150,
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,
const struct i2c_device_id *id)
const struct i2c_device_id *id)
{
const struct bma150_platform_data *pdata =
dev_get_platdata(&client->dev);
const struct bma150_cfg *cfg;
struct bma150_data *bma150;
struct input_dev *idev;
int chip_id;
int error;
......@@ -531,7 +436,7 @@ static int bma150_probe(struct i2c_client *client,
return -EINVAL;
}
bma150 = kzalloc(sizeof(struct bma150_data), GFP_KERNEL);
bma150 = devm_kzalloc(&client->dev, sizeof(*bma150), GFP_KERNEL);
if (!bma150)
return -ENOMEM;
......@@ -544,7 +449,7 @@ static int bma150_probe(struct i2c_client *client,
dev_err(&client->dev,
"IRQ GPIO conf. error %d, error %d\n",
client->irq, error);
goto err_free_mem;
return error;
}
}
cfg = &pdata->cfg;
......@@ -554,14 +459,42 @@ static int bma150_probe(struct i2c_client *client,
error = bma150_initialize(bma150, cfg);
if (error)
goto err_free_mem;
return error;
if (client->irq > 0) {
error = bma150_register_input_device(bma150);
idev = devm_input_allocate_device(&bma150->client->dev);
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)
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,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
BMA150_DRIVER, bma150);
......@@ -569,13 +502,8 @@ static int bma150_probe(struct i2c_client *client,
dev_err(&client->dev,
"irq request failed %d, error %d\n",
client->irq, error);
input_unregister_device(bma150->input);
goto err_free_mem;
return error;
}
} else {
error = bma150_register_polled_device(bma150);
if (error)
goto err_free_mem;
}
i2c_set_clientdata(client, bma150);
......@@ -583,33 +511,16 @@ static int bma150_probe(struct i2c_client *client,
pm_runtime_enable(&client->dev);
return 0;
err_free_mem:
kfree(bma150);
return error;
}
static int bma150_remove(struct i2c_client *client)
{
struct bma150_data *bma150 = i2c_get_clientdata(client);
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;
}
#ifdef CONFIG_PM
static int bma150_suspend(struct device *dev)
static int __maybe_unused bma150_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
struct bma150_data *bma150 = i2c_get_clientdata(client);
......@@ -617,14 +528,13 @@ static int bma150_suspend(struct device *dev)
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 bma150_data *bma150 = i2c_get_clientdata(client);
return bma150_set_mode(bma150, BMA150_MODE_NORMAL);
}
#endif
static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL);
......
......@@ -4,7 +4,8 @@
*
* 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/module.h>
#include <linux/platform_device.h>
......@@ -26,16 +27,14 @@ static const unsigned short cobalt_map[] = {
};
struct buttons_dev {
struct input_polled_dev *poll_dev;
unsigned short keymap[ARRAY_SIZE(cobalt_map)];
int count[ARRAY_SIZE(cobalt_map)];
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 input_dev *input = dev->input;
struct buttons_dev *bdev = input_get_drvdata(input);
uint32_t status;
int i;
......@@ -62,29 +61,33 @@ static void handle_buttons(struct input_polled_dev *dev)
static int cobalt_buttons_probe(struct platform_device *pdev)
{
struct buttons_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input;
struct resource *res;
int error, i;
bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL);
poll_dev = input_allocate_polled_device();
if (!bdev || !poll_dev) {
error = -ENOMEM;
goto err_free_mem;
}
bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
if (!bdev)
return -ENOMEM;
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));
poll_dev->private = bdev;
poll_dev->poll = handle_buttons;
poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
input = devm_input_allocate_device(&pdev->dev);
if (!input)
return -ENOMEM;
input_set_drvdata(input, bdev);
input = poll_dev->input;
input->name = "Cobalt buttons";
input->phys = "cobalt/input0";
input->id.bustype = BUS_HOST;
input->dev.parent = &pdev->dev;
input->keycode = bdev->keymap;
input->keycodemax = ARRAY_SIZE(bdev->keymap);
......@@ -96,39 +99,16 @@ static int cobalt_buttons_probe(struct platform_device *pdev)
__set_bit(bdev->keymap[i], 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)
goto err_iounmap;
return 0;
return error;
err_iounmap:
iounmap(bdev->reg);
err_free_mem:
input_free_polled_device(poll_dev);
kfree(bdev);
return error;
}
input_set_poll_interval(input, BUTTONS_POLL_INTERVAL);
static int cobalt_buttons_remove(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
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);
error = input_register_device(input);
if (error)
return error;
return 0;
}
......@@ -141,7 +121,6 @@ MODULE_ALIAS("platform:Cobalt buttons");
static struct platform_driver cobalt_buttons_driver = {
.probe = cobalt_buttons_probe,
.remove = cobalt_buttons_remove,
.driver = {
.name = "Cobalt buttons",
},
......
......@@ -17,14 +17,12 @@
#include <linux/device.h>
#include <linux/gpio/consumer.h>
#include <linux/input.h>
#include <linux/input-polldev.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
struct gpio_decoder {
struct input_polled_dev *poll_dev;
struct gpio_descs *input_gpios;
struct device *dev;
u32 axis;
......@@ -53,15 +51,15 @@ static int gpio_decoder_get_gpios_state(struct gpio_decoder *decoder)
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;
state = gpio_decoder_get_gpios_state(decoder);
if (state >= 0 && state != decoder->last_stable) {
input_report_abs(poll_dev->input, decoder->axis, state);
input_sync(poll_dev->input);
input_report_abs(input, decoder->axis, state);
input_sync(input);
decoder->last_stable = state;
}
}
......@@ -70,20 +68,23 @@ static int gpio_decoder_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct gpio_decoder *decoder;
struct input_polled_dev *poll_dev;
struct input_dev *input;
u32 max;
int err;
decoder = devm_kzalloc(dev, sizeof(struct gpio_decoder), GFP_KERNEL);
decoder = devm_kzalloc(dev, sizeof(*decoder), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
decoder->dev = dev;
device_property_read_u32(dev, "linux,axis", &decoder->axis);
decoder->input_gpios = devm_gpiod_get_array(dev, NULL, GPIOD_IN);
if (IS_ERR(decoder->input_gpios)) {
dev_err(dev, "unable to acquire input gpios\n");
return PTR_ERR(decoder->input_gpios);
}
if (decoder->input_gpios->ndescs < 2) {
dev_err(dev, "not enough gpios found\n");
return -EINVAL;
......@@ -92,22 +93,25 @@ static int gpio_decoder_probe(struct platform_device *pdev)
if (device_property_read_u32(dev, "decoder-max-value", &max))
max = (1U << decoder->input_gpios->ndescs) - 1;
decoder->dev = dev;
poll_dev = devm_input_allocate_polled_device(decoder->dev);
if (!poll_dev)
input = devm_input_allocate_device(dev);
if (!input)
return -ENOMEM;
poll_dev->private = decoder;
poll_dev->poll = gpio_decoder_poll_gpios;
decoder->poll_dev = poll_dev;
input_set_drvdata(input, decoder);
poll_dev->input->name = pdev->name;
poll_dev->input->id.bustype = BUS_HOST;
input_set_abs_params(poll_dev->input, decoder->axis, 0, max, 0, 0);
input->name = pdev->name;
input->id.bustype = BUS_HOST;
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) {
dev_err(dev, "failed to register polled device\n");
dev_err(dev, "failed to register input device\n");
return err;
}
......
This diff is collapsed.
......@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input/kxtj9.h>
#include <linux/input-polldev.h>
#define NAME "kxtj9"
#define G_MAX 8000
......@@ -71,9 +70,6 @@ struct kxtj9_data {
struct i2c_client *client;
struct kxtj9_platform_data pdata;
struct input_dev *input_dev;
#ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE
struct input_polled_dev *poll_dev;
#endif
unsigned int last_poll_interval;
u8 shift;
u8 ctrl_reg1;
......@@ -282,50 +278,6 @@ static void kxtj9_input_close(struct input_dev *dev)
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
* 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 = {
.attrs = kxtj9_attributes
};
#ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE
static void kxtj9_poll(struct input_polled_dev *dev)
static void kxtj9_poll(struct input_dev *input)
{
struct kxtj9_data *tj9 = dev->private;
unsigned int poll_interval = dev->poll_interval;
struct kxtj9_data *tj9 = input_get_drvdata(input);
unsigned int poll_interval = input_get_poll_interval(input);
kxtj9_report_acceleration_data(tj9);
......@@ -406,72 +356,14 @@ static void kxtj9_poll(struct input_polled_dev *dev)
}
}
static void kxtj9_polled_input_open(struct input_polled_dev *dev)
{
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)
static void kxtj9_platform_exit(void *data)
{
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)
{
int retval;
......@@ -494,11 +386,12 @@ static int kxtj9_verify(struct kxtj9_data *tj9)
}
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 =
dev_get_platdata(&client->dev);
struct kxtj9_data *tj9;
struct input_dev *input_dev;
int err;
if (!i2c_check_functionality(client->adapter,
......@@ -512,7 +405,7 @@ static int kxtj9_probe(struct i2c_client *client,
return -EINVAL;
}
tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL);
tj9 = devm_kzalloc(&client->dev, sizeof(*tj9), GFP_KERNEL);
if (!tj9) {
dev_err(&client->dev,
"failed to allocate memory for module data\n");
......@@ -525,13 +418,17 @@ static int kxtj9_probe(struct i2c_client *client,
if (pdata->init) {
err = pdata->init();
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);
if (err < 0) {
dev_err(&client->dev, "device not recognized\n");
goto err_pdata_exit;
return err;
}
i2c_set_clientdata(client, tj9);
......@@ -539,66 +436,62 @@ static int kxtj9_probe(struct i2c_client *client,
tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range;
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 in irq mode, populate INT_CTRL_REG1 and enable DRDY. */
tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL;
tj9->ctrl_reg1 |= DRDYE;
err = kxtj9_setup_input_device(tj9);
if (err)
goto err_pdata_exit;
err = request_threaded_irq(client->irq, NULL, kxtj9_isr,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"kxtj9-irq", tj9);
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL, kxtj9_isr,
IRQF_TRIGGER_RISING |
IRQF_ONESHOT,
"kxtj9-irq", tj9);
if (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) {
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;
}
......@@ -647,7 +540,6 @@ static struct i2c_driver kxtj9_driver = {
.pm = &kxtj9_pm_ops,
},
.probe = kxtj9_probe,
.remove = kxtj9_remove,
.id_table = kxtj9_id,
};
......
......@@ -10,7 +10,7 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/input-polldev.h>
#include <linux/input.h>
#include <linux/of_device.h>
#define MMA8450_DRV_NAME "mma8450"
......@@ -39,15 +39,8 @@
#define MMA8450_CTRL_REG1 0x38
#define MMA8450_CTRL_REG2 0x39
/* mma8450 status */
struct mma8450 {
struct i2c_client *client;
struct input_polled_dev *idev;
};
static int mma8450_read(struct mma8450 *m, unsigned off)
static int mma8450_read(struct i2c_client *c, unsigned int off)
{
struct i2c_client *c = m->client;
int ret;
ret = i2c_smbus_read_byte_data(c, off);
......@@ -59,9 +52,8 @@ static int mma8450_read(struct mma8450 *m, unsigned off)
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;
error = i2c_smbus_write_byte_data(c, off, v);
......@@ -75,10 +67,9 @@ static int mma8450_write(struct mma8450 *m, unsigned off, u8 v)
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)
{
struct i2c_client *c = m->client;
int err;
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,
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 ret;
u8 buf[6];
ret = mma8450_read(m, MMA8450_STATUS);
ret = mma8450_read(c, MMA8450_STATUS);
if (ret < 0)
return;
if (!(ret & MMA8450_STATUS_ZXYDR))
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)
return;
......@@ -114,41 +105,42 @@ static void mma8450_poll(struct input_polled_dev *dev)
y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
z = ((int)(s8)buf[5] << 4) | (buf[4] & 0xf);
input_report_abs(dev->input, ABS_X, x);
input_report_abs(dev->input, ABS_Y, y);
input_report_abs(dev->input, ABS_Z, z);
input_sync(dev->input);
input_report_abs(input, ABS_X, x);
input_report_abs(input, ABS_Y, y);
input_report_abs(input, ABS_Z, z);
input_sync(input);
}
/* 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;
/* 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)
return;
return err;
/*
* Sleep mode poll rate - 50Hz
* System output data rate - 400Hz
* Full scale selection - Active, +/- 2G
*/
err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01);
if (err < 0)
return;
err = mma8450_write(c, MMA8450_CTRL_REG1, 0x01);
if (err)
return err;
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(m, MMA8450_CTRL_REG2, 0x01);
mma8450_write(c, MMA8450_CTRL_REG1, 0x00);
mma8450_write(c, MMA8450_CTRL_REG2, 0x01);
}
/*
......@@ -157,38 +149,37 @@ static void mma8450_close(struct input_polled_dev *dev)
static int mma8450_probe(struct i2c_client *c,
const struct i2c_device_id *id)
{
struct input_polled_dev *idev;
struct mma8450 *m;
struct input_dev *input;
int err;
m = devm_kzalloc(&c->dev, sizeof(*m), GFP_KERNEL);
if (!m)
input = devm_input_allocate_device(&c->dev);
if (!input)
return -ENOMEM;
idev = devm_input_allocate_polled_device(&c->dev);
if (!idev)
return -ENOMEM;
input_set_drvdata(input, c);
input->name = MMA8450_DRV_NAME;
input->id.bustype = BUS_I2C;
input->open = mma8450_open;
input->close = mma8450_close;
m->client = c;
m->idev = idev;
input_set_abs_params(input, ABS_X, -2048, 2047, 32, 32);
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;
idev->input->name = MMA8450_DRV_NAME;
idev->input->id.bustype = BUS_I2C;
idev->poll = mma8450_poll;
idev->poll_interval = POLL_INTERVAL;
idev->poll_interval_max = POLL_INTERVAL_MAX;
idev->open = mma8450_open;
idev->close = mma8450_close;
err = input_setup_polling(input, mma8450_poll);
if (err) {
dev_err(&c->dev, "failed to set up polling\n");
return err;
}
__set_bit(EV_ABS, idev->input->evbit);
input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32);
input_set_abs_params(idev->input, ABS_Y, -2048, 2047, 32, 32);
input_set_abs_params(idev->input, ABS_Z, -2048, 2047, 32, 32);
input_set_poll_interval(input, POLL_INTERVAL);
input_set_max_poll_interval(input, POLL_INTERVAL_MAX);
err = input_register_polled_device(idev);
err = input_register_device(input);
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;
}
......
......@@ -5,7 +5,7 @@
* Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
*/
#include <linux/input-polldev.h>
#include <linux/input.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
......@@ -46,56 +46,42 @@ static bool rb532_button_pressed(void)
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,
rb532_button_pressed());
input_sync(poll_dev->input);
input_report_key(input, RB532_BTN_KSYM, rb532_button_pressed());
input_sync(input);
}
static int rb532_button_probe(struct platform_device *pdev)
{
struct input_polled_dev *poll_dev;
struct input_dev *input;
int error;
poll_dev = input_allocate_polled_device();
if (!poll_dev)
input = devm_input_allocate_device(&pdev->dev);
if (!input)
return -ENOMEM;
poll_dev->poll = rb532_button_poll;
poll_dev->poll_interval = RB532_BTN_RATE;
input->name = "rb532 button";
input->phys = "rb532/button0";
input->id.bustype = BUS_HOST;
poll_dev->input->name = "rb532 button";
poll_dev->input->phys = "rb532/button0";
poll_dev->input->id.bustype = BUS_HOST;
poll_dev->input->dev.parent = &pdev->dev;
input_set_capability(input, EV_KEY, RB532_BTN_KSYM);
dev_set_drvdata(&pdev->dev, poll_dev);
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);
error = input_setup_polling(input, rb532_button_poll);
if (error)
return error;
}
return 0;
}
input_set_poll_interval(input, RB532_BTN_RATE);
static int rb532_button_remove(struct platform_device *pdev)
{
struct input_polled_dev *poll_dev = dev_get_drvdata(&pdev->dev);
input_unregister_polled_device(poll_dev);
input_free_polled_device(poll_dev);
error = input_register_device(input);
if (error)
return error;
return 0;
}
static struct platform_driver rb532_button_driver = {
.probe = rb532_button_probe,
.remove = rb532_button_remove,
.driver = {
.name = DRV_NAME,
},
......
......@@ -4,7 +4,7 @@
*
* Copyright (C) 2008 Thomas Bogendoerfer <tsbogend@alpha.franken.de>
*/
#include <linux/input-polldev.h>
#include <linux/input.h>
#include <linux/ioport.h>
#include <linux/module.h>
#include <linux/platform_device.h>
......@@ -45,15 +45,13 @@ static const unsigned short sgi_map[] = {
};
struct buttons_dev {
struct input_polled_dev *poll_dev;
unsigned short keymap[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 input_dev *input = dev->input;
struct buttons_dev *bdev = input_get_drvdata(input);
u8 status;
int i;
......@@ -80,28 +78,24 @@ static void handle_buttons(struct input_polled_dev *dev)
static int sgi_buttons_probe(struct platform_device *pdev)
{
struct buttons_dev *bdev;
struct input_polled_dev *poll_dev;
struct input_dev *input;
int error, i;
bdev = kzalloc(sizeof(struct buttons_dev), GFP_KERNEL);
poll_dev = input_allocate_polled_device();
if (!bdev || !poll_dev) {
error = -ENOMEM;
goto err_free_mem;
}
bdev = devm_kzalloc(&pdev->dev, sizeof(*bdev), GFP_KERNEL);
if (!bdev)
return -ENOMEM;
input = devm_input_allocate_device(&pdev->dev);
if (!input)
return -ENOMEM;
memcpy(bdev->keymap, sgi_map, sizeof(bdev->keymap));
poll_dev->private = bdev;
poll_dev->poll = handle_buttons;
poll_dev->poll_interval = BUTTONS_POLL_INTERVAL;
input_set_drvdata(input, bdev);
input = poll_dev->input;
input->name = "SGI buttons";
input->phys = "sgi/input0";
input->id.bustype = BUS_HOST;
input->dev.parent = &pdev->dev;
input->keycode = bdev->keymap;
input->keycodemax = ARRAY_SIZE(bdev->keymap);
......@@ -113,35 +107,21 @@ static int sgi_buttons_probe(struct platform_device *pdev)
__set_bit(bdev->keymap[i], input->keybit);
__clear_bit(KEY_RESERVED, input->keybit);
bdev->poll_dev = poll_dev;
platform_set_drvdata(pdev, bdev);
error = input_register_polled_device(poll_dev);
error = input_setup_polling(input, handle_buttons);
if (error)
goto err_free_mem;
return error;
return 0;
input_set_poll_interval(input, BUTTONS_POLL_INTERVAL);
err_free_mem:
input_free_polled_device(poll_dev);
kfree(bdev);
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);
error = input_register_device(input);
if (error)
return error;
return 0;
}
static struct platform_driver sgi_buttons_driver = {
.probe = sgi_buttons_probe,
.remove = sgi_buttons_remove,
.driver = {
.name = "sgibtns",
},
......
......@@ -8,7 +8,7 @@
#include <linux/io.h>
#include <linux/dmi.h>
#include <linux/init.h>
#include <linux/input-polldev.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
......@@ -1030,7 +1030,7 @@ static int __init select_keymap(void)
/* Input layer interface */
static struct input_polled_dev *wistron_idev;
static struct input_dev *wistron_idev;
static unsigned long jiffies_last_press;
static bool wifi_enabled;
static bool bluetooth_enabled;
......@@ -1114,7 +1114,7 @@ static inline void wistron_led_resume(void)
static void handle_key(u8 code)
{
const struct key_entry *key =
sparse_keymap_entry_from_scancode(wistron_idev->input, code);
sparse_keymap_entry_from_scancode(wistron_idev, code);
if (key) {
switch (key->type) {
......@@ -1133,14 +1133,14 @@ static void handle_key(u8 code)
break;
default:
sparse_keymap_report_entry(wistron_idev->input,
key, 1, true);
sparse_keymap_report_entry(wistron_idev, key, 1, true);
break;
}
jiffies_last_press = jiffies;
} else
} else {
printk(KERN_NOTICE
"wistron_btns: Unknown key code %02X\n", code);
}
}
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 */
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);
/* Increase poll frequency if user is currently pressing keys (< 2s ago) */
if (time_before(jiffies, jiffies_last_press + 2 * HZ))
dev->poll_interval = POLL_INTERVAL_BURST;
input_set_poll_interval(dev, POLL_INTERVAL_BURST);
else
dev->poll_interval = POLL_INTERVAL_DEFAULT;
input_set_poll_interval(dev, POLL_INTERVAL_DEFAULT);
}
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)
{
struct input_dev *input_dev;
int error;
wistron_idev = input_allocate_polled_device();
wistron_idev = input_allocate_device();
if (!wistron_idev)
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->poll = wistron_poll;
wistron_idev->poll_interval = POLL_INTERVAL_DEFAULT;
input_dev = wistron_idev->input;
input_dev->name = "Wistron laptop buttons";
input_dev->phys = "wistron/input0";
input_dev->id.bustype = BUS_HOST;
input_dev->dev.parent = &wistron_device->dev;
error = sparse_keymap_setup(wistron_idev, keymap, wistron_setup_keymap);
if (error)
goto err_free_dev;
error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap);
error = input_setup_polling(wistron_idev, wistron_poll);
if (error)
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)
goto err_free_dev;
return 0;
err_free_dev:
input_free_polled_device(wistron_idev);
input_free_device(wistron_idev);
return error;
}
......@@ -1285,8 +1289,7 @@ static int wistron_probe(struct platform_device *dev)
static int wistron_remove(struct platform_device *dev)
{
wistron_led_remove();
input_unregister_polled_device(wistron_idev);
input_free_polled_device(wistron_idev);
input_unregister_device(wistron_idev);
bios_detach();
return 0;
......
......@@ -92,14 +92,14 @@ config MOUSE_PS2_SYNAPTICS_SMBUS
If unsure, say Y.
config MOUSE_PS2_CYPRESS
bool "Cypress PS/2 mouse protocol extension" if EXPERT
default y
depends on MOUSE_PS2
help
Say Y here if you have a Cypress PS/2 Trackpad connected to
your system.
bool "Cypress PS/2 mouse protocol extension" if EXPERT
default y
depends on MOUSE_PS2
help
Say Y here if you have a Cypress PS/2 Trackpad connected to
your system.
If unsure, say Y.
If unsure, say Y.
config MOUSE_PS2_LIFEBOOK
bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EXPERT
......@@ -381,7 +381,6 @@ config MOUSE_VSXXXAA
config MOUSE_GPIO
tristate "GPIO mouse"
depends on GPIOLIB || COMPILE_TEST
select INPUT_POLLDEV
help
This driver simulates a mouse on GPIO lines of various CPUs (and some
other chips).
......
......@@ -8,7 +8,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/input-polldev.h>
#include <linux/input.h>
#include <linux/gpio/consumer.h>
#include <linux/property.h>
#include <linux/of.h>
......@@ -43,10 +43,9 @@ struct gpio_mouse {
* 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.
*/
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 input_dev *input = dev->input;
struct gpio_mouse *gpio = input_get_drvdata(input);
int x, y;
if (gpio->bleft)
......@@ -71,18 +70,17 @@ static int gpio_mouse_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct gpio_mouse *gmouse;
struct input_polled_dev *input_poll;
struct input_dev *input;
int ret;
int error;
gmouse = devm_kzalloc(dev, sizeof(*gmouse), GFP_KERNEL);
if (!gmouse)
return -ENOMEM;
/* Assign some default scanning time */
ret = device_property_read_u32(dev, "scan-interval-ms",
&gmouse->scan_ms);
if (ret || gmouse->scan_ms == 0) {
error = device_property_read_u32(dev, "scan-interval-ms",
&gmouse->scan_ms);
if (error || gmouse->scan_ms == 0) {
dev_warn(dev, "invalid scan time, set to 50 ms\n");
gmouse->scan_ms = 50;
}
......@@ -112,23 +110,14 @@ static int gpio_mouse_probe(struct platform_device *pdev)
if (IS_ERR(gmouse->bright))
return PTR_ERR(gmouse->bright);
input_poll = devm_input_allocate_polled_device(dev);
if (!input_poll) {
dev_err(dev, "not enough memory for input device\n");
input = devm_input_allocate_device(dev);
if (!input)
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->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_Y);
......@@ -139,10 +128,16 @@ static int gpio_mouse_probe(struct platform_device *pdev)
if (gmouse->bright)
input_set_capability(input, EV_KEY, BTN_RIGHT);
ret = input_register_polled_device(input_poll);
if (ret) {
error = input_setup_polling(input, gpio_mouse_scan);
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");
return ret;
return error;
}
dev_dbg(dev, "%d ms scan time, buttons: %s%s%s\n",
......
......@@ -172,6 +172,7 @@ static const char * const smbus_pnp_ids[] = {
"LEN0071", /* T480 */
"LEN0072", /* X1 Carbon Gen 5 (2017) - Elan/ALPS trackpoint */
"LEN0073", /* X1 Carbon G5 (Elantech) */
"LEN0091", /* X1 Carbon 6 */
"LEN0092", /* X1 Carbon 6 */
"LEN0093", /* T480 */
"LEN0096", /* X280 */
......
......@@ -81,11 +81,6 @@ static const char * const rmi_f54_report_type_names[] = {
= "Full Raw Capacitance RX Offset Removed",
};
struct rmi_f54_reports {
int start;
int size;
};
struct f54_data {
struct rmi_function *fn;
......@@ -98,7 +93,6 @@ struct f54_data {
enum rmi_f54_report_type report_type;
u8 *report_data;
int report_size;
struct rmi_f54_reports standard_report[2];
bool is_busy;
struct mutex status_mutex;
......@@ -116,6 +110,7 @@ struct f54_data {
struct video_device vdev;
struct vb2_queue queue;
struct mutex lock;
u32 sequence;
int input;
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,
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);
u16 *ptr;
enum vb2_buffer_state state;
......@@ -298,6 +294,7 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb)
mutex_lock(&f54->status_mutex);
vb2_set_plane_payload(vb, 0, 0);
reptype = rmi_f54_get_reptype(f54, f54->input);
if (reptype == F54_REPORT_NONE) {
state = VB2_BUF_STATE_ERROR;
......@@ -344,14 +341,25 @@ static void rmi_f54_buffer_queue(struct vb2_buffer *vb)
data_done:
mutex_unlock(&f54->data_mutex);
done:
vb->timestamp = ktime_get_ns();
vbuf->field = V4L2_FIELD_NONE;
vbuf->sequence = f54->sequence++;
vb2_buffer_done(vb, state);
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 */
static const struct vb2_ops rmi_f54_queue_ops = {
.queue_setup = rmi_f54_queue_setup,
.buf_queue = rmi_f54_buffer_queue,
.stop_streaming = rmi_f54_stop_streaming,
.wait_prepare = vb2_ops_wait_prepare,
.wait_finish = vb2_ops_wait_finish,
};
......@@ -363,7 +371,6 @@ static const struct vb2_queue rmi_f54_queue = {
.ops = &rmi_f54_queue_ops,
.mem_ops = &vb2_vmalloc_memops,
.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC,
.min_buffers_needed = 1,
};
static int rmi_f54_vidioc_querycap(struct file *file, void *priv,
......@@ -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 rmi_function *fn = f54->fn;
u8 fifo[2];
struct rmi_f54_reports *report;
int report_size;
u8 command;
u8 *data;
int error;
data = f54->report_data;
report_size = rmi_f54_get_report_size(f54);
if (report_size == 0) {
dev_err(&fn->dev, "Bad report size, report type=%d\n",
......@@ -530,8 +534,6 @@ static void rmi_f54_work(struct work_struct *work)
error = -EINVAL;
goto error; /* retry won't help */
}
f54->standard_report[0].size = report_size;
report = f54->standard_report;
mutex_lock(&f54->data_mutex);
......@@ -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");
report_size = 0;
for (; report->size; report++) {
fifo[0] = report->start & 0xff;
fifo[1] = (report->start >> 8) & 0xff;
error = rmi_write_block(fn->rmi_dev,
fn->fd.data_base_addr + F54_FIFO_OFFSET,
fifo, sizeof(fifo));
if (error) {
dev_err(&fn->dev, "Failed to set fifo start offset\n");
goto abort;
}
fifo[0] = 0;
fifo[1] = 0;
error = rmi_write_block(fn->rmi_dev,
fn->fd.data_base_addr + F54_FIFO_OFFSET,
fifo, sizeof(fifo));
if (error) {
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 +
F54_REPORT_DATA_OFFSET, data,
report->size);
if (error) {
dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n",
__func__, report->size, error);
goto abort;
}
data += report->size;
report_size += report->size;
error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr +
F54_REPORT_DATA_OFFSET, f54->report_data,
report_size);
if (error) {
dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n",
__func__, report_size, error);
goto abort;
}
abort:
......
......@@ -39,16 +39,16 @@ config TABLET_USB_AIPTEK
module will be called aiptek.
config TABLET_USB_GTCO
tristate "GTCO CalComp/InterWrite USB Support"
depends on USB && INPUT
help
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"
(CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
(CONFIG_INPUT_EVDEV) as well.
To compile this driver as a module, choose M here: the
module will be called gtco.
tristate "GTCO CalComp/InterWrite USB Support"
depends on USB && INPUT
help
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"
(CONFIG_INPUT_MOUSEDEV) and/or "Event interface support"
(CONFIG_INPUT_EVDEV) as well.
To compile this driver as a module, choose M here: the
module will be called gtco.
config TABLET_USB_HANWANG
tristate "Hanwang Art Master III tablet support (USB)"
......
......@@ -633,7 +633,7 @@ config TOUCHSCREEN_HP600
depends on SH_HP6XX && SH_ADC
help
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
module will be called hp680_ts_input.
......@@ -700,7 +700,6 @@ config TOUCHSCREEN_EDT_FT5X06
config TOUCHSCREEN_RASPBERRYPI_FW
tristate "Raspberry Pi's firmware base touch screen support"
depends on RASPBERRYPI_FIRMWARE || (RASPBERRYPI_FIRMWARE=n && COMPILE_TEST)
select INPUT_POLLDEV
help
Say Y here if you have the official Raspberry Pi 7 inch screen on
your system.
......@@ -1038,7 +1037,6 @@ config TOUCHSCREEN_TS4800
depends on HAS_IOMEM && OF
depends on SOC_IMX51 || COMPILE_TEST
select MFD_SYSCON
select INPUT_POLLDEV
help
Say Y here if you have a touchscreen on a TS-4800 board.
......@@ -1210,7 +1208,6 @@ config TOUCHSCREEN_SUR40
tristate "Samsung SUR40 (Surface 2.0/PixelSense) touchscreen"
depends on USB && MEDIA_USB_SUPPORT && HAS_DMA
depends on VIDEO_V4L2
select INPUT_POLLDEV
select VIDEOBUF2_DMA_SG
help
Say Y here if you want support for the Samsung SUR40 touchscreen
......@@ -1246,7 +1243,6 @@ config TOUCHSCREEN_SX8654
config TOUCHSCREEN_TPS6507X
tristate "TPS6507x based touchscreens"
depends on I2C
select INPUT_POLLDEV
help
Say Y here if you have a TPS6507x based touchscreen
controller.
......
......@@ -13,7 +13,7 @@
#include <linux/irq.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_Y 4095
......@@ -25,7 +25,7 @@
struct ar1021_i2c {
struct i2c_client *client;
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)
......
......@@ -3156,6 +3156,8 @@ static int __maybe_unused mxt_suspend(struct device *dev)
mutex_unlock(&input_dev->mutex);
disable_irq(data->irq);
return 0;
}
......@@ -3168,6 +3170,8 @@ static int __maybe_unused mxt_resume(struct device *dev)
if (!input_dev)
return 0;
enable_irq(data->irq);
mutex_lock(&input_dev->mutex);
if (input_dev->users)
......
......@@ -9,7 +9,6 @@
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/iio/consumer.h>
#include <linux/iio/types.h>
......
......@@ -28,6 +28,7 @@
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <asm/unaligned.h>
#include <linux/regulator/consumer.h>
#define WORK_REGISTER_THRESHOLD 0x00
#define WORK_REGISTER_REPORT_RATE 0x08
......@@ -88,6 +89,7 @@ struct edt_ft5x06_ts_data {
struct touchscreen_properties prop;
u16 num_x;
u16 num_y;
struct regulator *vcc;
struct gpio_desc *reset_gpio;
struct gpio_desc *wake_gpio;
......@@ -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,
const struct i2c_device_id *id)
{
......@@ -1064,6 +1073,27 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
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,
"reset", GPIOD_OUT_HIGH);
if (IS_ERR(tsdata->reset_gpio)) {
......
This diff is collapsed.
......@@ -446,8 +446,7 @@ static int mms114_probe(struct i2c_client *client,
data->client = client;
data->input_dev = input_dev;
/* FIXME: switch to device_get_match_data() when available */
match_data = of_device_get_match_data(&client->dev);
match_data = device_get_match_data(&client->dev);
if (!match_data)
return -EINVAL;
......
......@@ -5,22 +5,73 @@
* Copyright (C) 2010-2011 Pixcir, Inc.
*/
#include <asm/unaligned.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input/touchscreen.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/interrupt.h>
#include <linux/of_device.h>
#include <linux/platform_data/pixcir_i2c_ts.h>
#include <asm/unaligned.h>
#include <linux/module.h>
#include <linux/slab.h>
#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 i2c_client *client;
struct input_dev *input;
......@@ -30,7 +81,6 @@ struct pixcir_i2c_ts_data {
struct gpio_desc *gpio_wake;
const struct pixcir_i2c_chip_data *chip;
struct touchscreen_properties prop;
int max_fingers; /* Max fingers supported in this instance */
bool running;
};
......@@ -54,7 +104,7 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
memset(report, 0, sizeof(struct pixcir_report_data));
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))
readsize = sizeof(rdbuf);
......@@ -75,8 +125,8 @@ static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata,
}
touch = rdbuf[0] & 0x7;
if (touch > tsdata->max_fingers)
touch = tsdata->max_fingers;
if (touch > tsdata->chip->max_fingers)
touch = tsdata->chip->max_fingers;
report->num_touches = touch;
bufptr = &rdbuf[2];
......@@ -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);
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);
return ret;
}
......@@ -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);
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);
return ret;
}
......@@ -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);
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);
return ret;
}
......@@ -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);
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);
return ret;
}
......@@ -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);
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);
return ret;
}
......@@ -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);
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);
return ret;
}
......@@ -412,31 +462,9 @@ static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops,
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,
const struct i2c_device_id *id)
{
const struct pixcir_ts_platform_data *pdata =
dev_get_platdata(&client->dev);
struct device *dev = &client->dev;
struct pixcir_i2c_ts_data *tsdata;
struct input_dev *input;
......@@ -446,19 +474,11 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
if (!tsdata)
return -ENOMEM;
if (pdata) {
tsdata->chip = &pdata->chip;
} else if (dev->of_node) {
error = pixcir_parse_dt(dev, tsdata);
if (error)
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");
tsdata->chip = device_get_match_data(dev);
if (!tsdata->chip && id)
tsdata->chip = (const void *)id->driver_data;
if (!tsdata->chip) {
dev_err(dev, "can't locate chip data\n");
return -EINVAL;
}
......@@ -475,30 +495,17 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
input->id.bustype = BUS_I2C;
input->open = pixcir_input_open;
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;
if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) {
tsdata->max_fingers = PIXCIR_MAX_SLOTS;
dev_info(dev, "Limiting maximum fingers to %d\n",
tsdata->max_fingers);
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;
}
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);
if (error) {
dev_err(dev, "Error initializing Multi-Touch slots\n");
......@@ -510,7 +517,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN);
if (IS_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;
}
......@@ -518,7 +527,9 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
GPIOD_OUT_LOW);
if (IS_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;
}
......@@ -574,14 +585,6 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client,
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 = {
.max_fingers = 2,
/* no hw id support */
......@@ -592,6 +595,14 @@ static const struct pixcir_i2c_chip_data pixcir_tangoc_data = {
.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[] = {
{ .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data },
{ .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data },
......
......@@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/input-polldev.h>
#include <linux/input/touchscreen.h>
#include <soc/bcm2835/raspberrypi-firmware.h>
......@@ -34,7 +33,7 @@
struct rpi_ts {
struct platform_device *pdev;
struct input_polled_dev *poll_dev;
struct input_dev *input;
struct touchscreen_properties prop;
void __iomem *fw_regs_va;
......@@ -57,10 +56,9 @@ struct rpi_ts_regs {
} 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 = dev->private;
struct rpi_ts *ts = input_get_drvdata(input);
struct rpi_ts_regs regs;
int modified_ids = 0;
long released_ids;
......@@ -123,10 +121,9 @@ static int rpi_ts_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct input_polled_dev *poll_dev;
struct input_dev *input;
struct device_node *fw_node;
struct rpi_firmware *fw;
struct input_dev *input;
struct rpi_ts *ts;
u32 touchbuf;
int error;
......@@ -160,7 +157,6 @@ static int rpi_ts_probe(struct platform_device *pdev)
return error;
}
touchbuf = (u32)ts->fw_regs_phys;
error = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_SET_TOUCHBUF,
&touchbuf, sizeof(touchbuf));
......@@ -170,19 +166,17 @@ static int rpi_ts_probe(struct platform_device *pdev)
return error;
}
poll_dev = devm_input_allocate_polled_device(dev);
if (!poll_dev) {
input = devm_input_allocate_device(dev);
if (!input) {
dev_err(dev, "Failed to allocate input device\n");
return -ENOMEM;
}
ts->poll_dev = poll_dev;
input = poll_dev->input;
ts->input = input;
input_set_drvdata(input, ts);
input->name = "raspberrypi-ts";
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,
RPI_TS_DEFAULT_WIDTH, 0, 0);
......@@ -197,7 +191,15 @@ static int rpi_ts_probe(struct platform_device *pdev)
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) {
dev_err(dev, "could not register input device, %d\n", error);
return error;
......@@ -214,10 +216,10 @@ MODULE_DEVICE_TABLE(of, rpi_ts_match);
static struct platform_driver rpi_ts_driver = {
.driver = {
.name = "raspberrypi-ts",
.name = "raspberrypi-ts",
.of_match_table = rpi_ts_match,
},
.probe = rpi_ts_probe,
.probe = rpi_ts_probe,
};
module_platform_driver(rpi_ts_driver);
......
......@@ -13,7 +13,6 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/delay.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 @@
#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <asm/unaligned.h>
#define WACOM_CMD_QUERY0 0x04
......
......@@ -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_min_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 *);
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