Merge branch 'next' into for-linus

Prepare input updates for 4.11 merge window.
This commit is contained in:
Dmitry Torokhov
2017-02-20 15:16:02 -08:00
133 changed files with 2328 additions and 2249 deletions
@@ -0,0 +1,27 @@
Samsung tm2-touchkey
Required properties:
- compatible: must be "cypress,tm2-touchkey"
- reg: I2C address of the chip.
- interrupt-parent: a phandle for the interrupt controller (see interrupt
binding[0]).
- interrupts: interrupt to which the chip is connected (see interrupt
binding[0]).
- vcc-supply : internal regulator output. 1.8V
- vdd-supply : power supply for IC 3.3V
[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
&i2c0 {
/* ... */
touchkey@20 {
compatible = "cypress,tm2-touchkey";
reg = <0x20>;
interrupt-parent = <&gpa3>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
vcc-supply=<&ldo32_reg>;
vdd-supply=<&ldo33_reg>;
};
};
@@ -0,0 +1,30 @@
* 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>;
};
@@ -5,3 +5,19 @@ Registers a PWM device as beeper.
Required properties:
- compatible: should be "pwm-beeper"
- pwms: phandle to the physical PWM device
Optional properties:
- amp-supply: phandle to a regulator that acts as an amplifier for the beeper
Example:
beeper_amp: amplifier {
compatible = "fixed-regulator";
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
};
beeper {
compatible = "pwm-beeper";
pwms = <&pwm0>;
amp-supply = <&beeper_amp>;
};
@@ -0,0 +1,32 @@
Zeitec ZET6223 I2C touchscreen controller
Required properties:
- compatible : "zeitec,zet6223"
- reg : I2C slave address of the chip (0x76)
- interrupt-parent : a phandle pointing to the interrupt controller
serving the interrupt for this chip
- interrupts : interrupt specification for the zet6223 interrupt
Optional properties:
- vio-supply : Specification for VIO supply (1.8V or 3.3V,
depending on system interface needs).
- vcc-supply : Specification for 3.3V VCC supply.
- touchscreen-size-x : See touchscreen.txt
- touchscreen-size-y : See touchscreen.txt
- touchscreen-inverted-x : See touchscreen.txt
- touchscreen-inverted-y : See touchscreen.txt
- touchscreen-swapped-x-y : See touchscreen.txt
Example:
i2c@00000000 {
zet6223: touchscreen@76 {
compatible = "zeitec,zet6223";
reg = <0x76>;
interrupt-parent = <&pio>;
interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>
};
};
@@ -329,6 +329,7 @@ xes Extreme Engineering Solutions (X-ES)
xillybus Xillybus Ltd.
xlnx Xilinx
zarlink Zarlink Semiconductor
zeitec ZEITEC Semiconductor Co., LTD.
zii Zodiac Inflight Innovations
zte ZTE Corp.
zyxel ZyXEL Communications Corp.
-3
View File
@@ -94,7 +94,6 @@ comment "Userland interfaces"
config INPUT_MOUSEDEV
tristate "Mouse interface"
default y
help
Say Y here if you want your mouse to be accessible as char devices
13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
@@ -109,7 +108,6 @@ config INPUT_MOUSEDEV
config INPUT_MOUSEDEV_PSAUX
bool "Provide legacy /dev/psaux device"
default y
depends on INPUT_MOUSEDEV
help
Say Y here if you want your mouse also be accessible as char device
@@ -118,7 +116,6 @@ config INPUT_MOUSEDEV_PSAUX
If unsure, say Y.
config INPUT_MOUSEDEV_SCREEN_X
int "Horizontal screen resolution"
depends on INPUT_MOUSEDEV
+7 -1
View File
@@ -1749,7 +1749,7 @@ static const struct dev_pm_ops input_dev_pm_ops = {
};
#endif /* CONFIG_PM */
static struct device_type input_dev_type = {
static const struct device_type input_dev_type = {
.groups = input_dev_attr_groups,
.release = input_dev_release,
.uevent = input_dev_uevent,
@@ -2091,6 +2091,12 @@ int input_register_device(struct input_dev *dev)
const char *path;
int error;
if (test_bit(EV_ABS, dev->evbit) && !dev->absinfo) {
dev_err(&dev->dev,
"Absolute device without dev->absinfo, refusing to register\n");
return -EINVAL;
}
if (dev->devres_managed) {
devres = devres_alloc(devm_input_device_unregister,
sizeof(struct input_devres), GFP_KERNEL);
+14 -6
View File
@@ -87,7 +87,7 @@ static int joydev_correct(int value, struct js_corr *corr)
return 0;
}
return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
return clamp(value, -32767, 32767);
}
static void joydev_pass_event(struct joydev_client *client,
@@ -187,6 +187,17 @@ static void joydev_detach_client(struct joydev *joydev,
synchronize_rcu();
}
static void joydev_refresh_state(struct joydev *joydev)
{
struct input_dev *dev = joydev->handle.dev;
int i, val;
for (i = 0; i < joydev->nabs; i++) {
val = input_abs_get_val(dev, joydev->abspam[i]);
joydev->abs[i] = joydev_correct(val, &joydev->corr[i]);
}
}
static int joydev_open_device(struct joydev *joydev)
{
int retval;
@@ -201,6 +212,8 @@ static int joydev_open_device(struct joydev *joydev)
retval = input_open_device(&joydev->handle);
if (retval)
joydev->open--;
else
joydev_refresh_state(joydev);
}
mutex_unlock(&joydev->mutex);
@@ -872,7 +885,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
j = joydev->abspam[i];
if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) {
joydev->corr[i].type = JS_CORR_NONE;
joydev->abs[i] = input_abs_get_val(dev, j);
continue;
}
joydev->corr[i].type = JS_CORR_BROKEN;
@@ -887,10 +899,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
if (t) {
joydev->corr[i].coef[2] = (1 << 29) / t;
joydev->corr[i].coef[3] = (1 << 29) / t;
joydev->abs[i] =
joydev_correct(input_abs_get_val(dev, j),
joydev->corr + i);
}
}
-1
View File
@@ -139,7 +139,6 @@ static int probe_maple_controller(struct device *dev)
idev->dev.parent = &mdev->dev;
idev->name = mdev->product_name;
idev->id.bustype = BUS_HOST;
input_set_drvdata(idev, pad);
error = input_register_device(idev);
if (error)
+95 -61
View File
@@ -320,18 +320,18 @@ static struct usb_device_id xpad_table[] = {
XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */
XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
{ }
};
@@ -389,6 +389,7 @@ struct usb_xpad {
static int xpad_init_input(struct usb_xpad *xpad);
static void xpad_deinit_input(struct usb_xpad *xpad);
static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
/*
* xpad_process_packet
@@ -608,14 +609,36 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
}
/*
* xpadone_process_buttons
* xpadone_process_packet
*
* Process a button update packet from an Xbox one controller.
* Completes a request by converting the data into events for the
* input subsystem. This version is for the Xbox One controller.
*
* The report format was gleaned from
* https://github.com/kylelemons/xbox/blob/master/xbox.go
*/
static void xpadone_process_buttons(struct usb_xpad *xpad,
struct input_dev *dev,
unsigned char *data)
static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
/* the xbox button has its own special report */
if (data[0] == 0X07) {
/*
* The Xbox One S controller requires these reports to be
* acked otherwise it continues sending them forever and
* won't report further mode button events.
*/
if (data[1] == 0x30)
xpadone_ack_mode_report(xpad, data[2]);
input_report_key(dev, BTN_MODE, data[4] & 0x01);
input_sync(dev);
return;
}
/* check invalid packet */
else if (data[0] != 0X20)
return;
/* menu/view buttons */
input_report_key(dev, BTN_START, data[4] & 0x04);
input_report_key(dev, BTN_SELECT, data[4] & 0x08);
@@ -678,34 +701,6 @@ static void xpadone_process_buttons(struct usb_xpad *xpad,
input_sync(dev);
}
/*
* xpadone_process_packet
*
* Completes a request by converting the data into events for the
* input subsystem. This version is for the Xbox One controller.
*
* The report format was gleaned from
* https://github.com/kylelemons/xbox/blob/master/xbox.go
*/
static void xpadone_process_packet(struct usb_xpad *xpad,
u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
switch (data[0]) {
case 0x20:
xpadone_process_buttons(xpad, dev, data);
break;
case 0x07:
/* the xbox button has its own special report */
input_report_key(dev, BTN_MODE, data[4] & 0x01);
input_sync(dev);
break;
}
}
static void xpad_irq_in(struct urb *urb)
{
struct usb_xpad *xpad = urb->context;
@@ -850,10 +845,9 @@ static void xpad_irq_out(struct urb *urb)
spin_unlock_irqrestore(&xpad->odata_lock, flags);
}
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
struct usb_endpoint_descriptor *ep_irq_out)
{
struct usb_endpoint_descriptor *ep_irq_out;
int ep_irq_out_idx;
int error;
if (xpad->xtype == XTYPE_UNKNOWN)
@@ -863,23 +857,17 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->odata_dma);
if (!xpad->odata) {
error = -ENOMEM;
goto fail1;
}
if (!xpad->odata)
return -ENOMEM;
spin_lock_init(&xpad->odata_lock);
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->irq_out) {
error = -ENOMEM;
goto fail2;
goto err_free_coherent;
}
/* Xbox One controller has in/out endpoints swapped. */
ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
usb_fill_int_urb(xpad->irq_out, xpad->udev,
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
xpad->odata, XPAD_PKT_LEN,
@@ -889,8 +877,9 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
return 0;
fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
fail1: return error;
err_free_coherent:
usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
return error;
}
static void xpad_stop_output(struct usb_xpad *xpad)
@@ -974,6 +963,30 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
return retval;
}
static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
{
unsigned long flags;
struct xpad_output_packet *packet =
&xpad->out_packets[XPAD_OUT_CMD_IDX];
static const u8 mode_report_ack[] = {
0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00
};
spin_lock_irqsave(&xpad->odata_lock, flags);
packet->len = sizeof(mode_report_ack);
memcpy(packet->data, mode_report_ack, packet->len);
packet->data[2] = seq_num;
packet->pending = true;
/* Reset the sequence so we send out the ack now */
xpad->last_out_packet = -1;
xpad_try_sending_next_out_packet(xpad);
spin_unlock_irqrestore(&xpad->odata_lock, flags);
}
#ifdef CONFIG_JOYSTICK_XPAD_FF
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
@@ -1198,6 +1211,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
led_cdev = &led->led_cdev;
led_cdev->name = led->name;
led_cdev->brightness_set = xpad_led_set;
led_cdev->flags = LED_CORE_SUSPENDRESUME;
error = led_classdev_register(&xpad->udev->dev, led_cdev);
if (error)
@@ -1468,8 +1482,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_xpad *xpad;
struct usb_endpoint_descriptor *ep_irq_in;
int ep_irq_in_idx;
struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
int i, error;
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
@@ -1539,14 +1552,27 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
goto err_free_in_urb;
}
error = xpad_init_output(intf, xpad);
ep_irq_in = ep_irq_out = NULL;
for (i = 0; i < 2; i++) {
struct usb_endpoint_descriptor *ep =
&intf->cur_altsetting->endpoint[i].desc;
if (usb_endpoint_dir_in(ep))
ep_irq_in = ep;
else
ep_irq_out = ep;
}
if (!ep_irq_in || !ep_irq_out) {
error = -ENODEV;
goto err_free_in_urb;
}
error = xpad_init_output(intf, xpad, ep_irq_out);
if (error)
goto err_free_in_urb;
/* Xbox One controller has in/out endpoints swapped. */
ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
@@ -1662,8 +1688,16 @@ static int xpad_resume(struct usb_interface *intf)
retval = xpad360w_start_input(xpad);
} else {
mutex_lock(&input->mutex);
if (input->users)
if (input->users) {
retval = xpad_start_input(xpad);
} else if (xpad->xtype == XTYPE_XBOXONE) {
/*
* Even if there are no users, we'll send Xbox One pads
* the startup sequence so they don't sit there and
* blink until somebody opens the input device again.
*/
retval = xpad_start_xbox_one(xpad);
}
mutex_unlock(&input->mutex);
}
+11
View File
@@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
To compile this driver as a module, choose M here: the
module will be called tc3589x-keypad.
config KEYBOARD_TM2_TOUCHKEY
tristate "TM2 touchkey support"
depends on I2C
depends on LEDS_CLASS
help
Say Y here to enable device driver for tm2-touchkey with
LED control for the Exynos5433 TM2 board.
To compile this driver as a module, choose M here.
module will be called tm2-touchkey.
config KEYBOARD_TWL4030
tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
depends on TWL4030_CORE
+1
View File
@@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY) += tm2-touchkey.o
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
-2
View File
@@ -148,8 +148,6 @@ static int adc_keys_probe(struct platform_device *pdev)
if (error)
return error;
platform_set_drvdata(pdev, st);
poll_dev = devm_input_allocate_polled_device(dev);
if (!poll_dev) {
dev_err(dev, "failed to allocate input device\n");
-2
View File
@@ -107,8 +107,6 @@ static int adp5520_keys_probe(struct platform_device *pdev)
input->phys = "adp5520-keys/input0";
input->dev.parent = &pdev->dev;
input_set_drvdata(input, dev);
input->id.bustype = BUS_I2C;
input->id.vendor = 0x0001;
input->id.product = 0x5520;
+1 -3
View File
@@ -213,7 +213,7 @@ static int bcm_kp_matrix_key_parse_dt(struct bcm_kp *kp)
/* Initialize the KPCR Keypad Configuration Register */
kp->kpcr = KPCR_STATUSFILTERENABLE | KPCR_COLFILTERENABLE;
error = matrix_keypad_parse_of_params(dev, &kp->n_rows, &kp->n_cols);
error = matrix_keypad_parse_properties(dev, &kp->n_rows, &kp->n_cols);
if (error) {
dev_err(dev, "failed to parse kp params\n");
return error;
@@ -352,8 +352,6 @@ static int bcm_kp_probe(struct platform_device *pdev)
kp->input_dev = input_dev;
platform_set_drvdata(pdev, kp);
error = bcm_kp_matrix_key_parse_dt(kp);
if (error)
return error;
-2
View File
@@ -268,8 +268,6 @@ static int bfin_kpad_probe(struct platform_device *pdev)
input->phys = "bf54x-keys/input0";
input->dev.parent = &pdev->dev;
input_set_drvdata(input, bf54x_kpad);
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
-1
View File
@@ -392,7 +392,6 @@ static int cap11xx_i2c_probe(struct i2c_client *i2c_client,
return error;
dev_info(dev, "CAP11XX detected, revision 0x%02x\n", rev);
i2c_set_clientdata(i2c_client, priv);
node = dev->of_node;
if (!of_property_read_u32(node, "microchip,sensor-gain", &gain32)) {
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -172,7 +172,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev)
struct input_dev *key_dev;
struct resource *res, *mem;
struct device *dev = &pdev->dev;
struct davinci_ks_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct davinci_ks_platform_data *pdata = dev_get_platdata(dev);
int error, i;
if (pdata->device_enable) {
@@ -255,7 +255,7 @@ static int __init davinci_ks_probe(struct platform_device *pdev)
key_dev->name = "davinci_keyscan";
key_dev->phys = "davinci_keyscan/input0";
key_dev->dev.parent = &pdev->dev;
key_dev->dev.parent = dev;
key_dev->id.bustype = BUS_HOST;
key_dev->id.vendor = 0x0001;
key_dev->id.product = 0x0001;
+39 -27
View File
@@ -36,6 +36,8 @@ struct gpio_button_data {
struct input_dev *input;
struct gpio_desc *gpiod;
unsigned short *code;
struct timer_list release_timer;
unsigned int release_delay; /* in msecs, for IRQ-only buttons */
@@ -52,6 +54,7 @@ struct gpio_keys_drvdata {
const struct gpio_keys_platform_data *pdata;
struct input_dev *input;
struct mutex disable_lock;
unsigned short *keymap;
struct gpio_button_data data[0];
};
@@ -203,7 +206,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
if (only_disabled && !bdata->disabled)
continue;
__set_bit(bdata->button->code, bits);
__set_bit(*bdata->code, bits);
}
ret = scnprintf(buf, PAGE_SIZE - 1, "%*pbl", n_events, bits);
@@ -254,7 +257,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
if (bdata->button->type != type)
continue;
if (test_bit(bdata->button->code, bits) &&
if (test_bit(*bdata->code, bits) &&
!bdata->button->can_disable) {
error = -EINVAL;
goto out;
@@ -269,7 +272,7 @@ static ssize_t gpio_keys_attr_store_helper(struct gpio_keys_drvdata *ddata,
if (bdata->button->type != type)
continue;
if (test_bit(bdata->button->code, bits))
if (test_bit(*bdata->code, bits))
gpio_keys_disable_button(bdata);
else
gpio_keys_enable_button(bdata);
@@ -371,7 +374,7 @@ static void gpio_keys_gpio_report_event(struct gpio_button_data *bdata)
if (state)
input_event(input, type, button->code, button->value);
} else {
input_event(input, type, button->code, state);
input_event(input, type, *bdata->code, state);
}
input_sync(input);
}
@@ -411,7 +414,7 @@ static void gpio_keys_irq_timer(unsigned long _data)
spin_lock_irqsave(&bdata->lock, flags);
if (bdata->key_pressed) {
input_event(input, EV_KEY, bdata->button->code, 0);
input_event(input, EV_KEY, *bdata->code, 0);
input_sync(input);
bdata->key_pressed = false;
}
@@ -421,7 +424,6 @@ static void gpio_keys_irq_timer(unsigned long _data)
static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
{
struct gpio_button_data *bdata = dev_id;
const struct gpio_keys_button *button = bdata->button;
struct input_dev *input = bdata->input;
unsigned long flags;
@@ -433,11 +435,11 @@ static irqreturn_t gpio_keys_irq_isr(int irq, void *dev_id)
if (bdata->button->wakeup)
pm_wakeup_event(bdata->input->dev.parent, 0);
input_event(input, EV_KEY, button->code, 1);
input_event(input, EV_KEY, *bdata->code, 1);
input_sync(input);
if (!bdata->release_delay) {
input_event(input, EV_KEY, button->code, 0);
input_event(input, EV_KEY, *bdata->code, 0);
input_sync(input);
goto out;
}
@@ -465,12 +467,14 @@ static void gpio_keys_quiesce_key(void *data)
static int gpio_keys_setup_key(struct platform_device *pdev,
struct input_dev *input,
struct gpio_button_data *bdata,
struct gpio_keys_drvdata *ddata,
const struct gpio_keys_button *button,
int idx,
struct fwnode_handle *child)
{
const char *desc = button->desc ? button->desc : "gpio_keys";
struct device *dev = &pdev->dev;
struct gpio_button_data *bdata = &ddata->data[idx];
irq_handler_t isr;
unsigned long irqflags;
int irq;
@@ -514,8 +518,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
if (button->active_low)
flags |= GPIOF_ACTIVE_LOW;
error = devm_gpio_request_one(&pdev->dev, button->gpio, flags,
desc);
error = devm_gpio_request_one(dev, button->gpio, flags, desc);
if (error < 0) {
dev_err(dev, "Failed to request GPIO %d, error %d\n",
button->gpio, error);
@@ -577,16 +580,17 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
irqflags = 0;
}
input_set_capability(input, button->type ?: EV_KEY, button->code);
bdata->code = &ddata->keymap[idx];
*bdata->code = button->code;
input_set_capability(input, button->type ?: EV_KEY, *bdata->code);
/*
* Install custom action to cancel release timer and
* workqueue item.
*/
error = devm_add_action(&pdev->dev, gpio_keys_quiesce_key, bdata);
error = devm_add_action(dev, gpio_keys_quiesce_key, bdata);
if (error) {
dev_err(&pdev->dev,
"failed to register quiesce action, error: %d\n",
dev_err(dev, "failed to register quiesce action, error: %d\n",
error);
return error;
}
@@ -598,8 +602,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
if (!button->can_disable)
irqflags |= IRQF_SHARED;
error = devm_request_any_context_irq(&pdev->dev, bdata->irq,
isr, irqflags, desc, bdata);
error = devm_request_any_context_irq(dev, bdata->irq, isr, irqflags,
desc, bdata);
if (error < 0) {
dev_err(dev, "Unable to claim irq %d; error %d\n",
bdata->irq, error);
@@ -750,6 +754,12 @@ static int gpio_keys_probe(struct platform_device *pdev)
return -ENOMEM;
}
ddata->keymap = devm_kcalloc(dev,
pdata->nbuttons, sizeof(ddata->keymap[0]),
GFP_KERNEL);
if (!ddata->keymap)
return -ENOMEM;
input = devm_input_allocate_device(dev);
if (!input) {
dev_err(dev, "failed to allocate input device\n");
@@ -765,7 +775,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
input->name = pdata->name ? : pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
input->dev.parent = dev;
input->open = gpio_keys_open;
input->close = gpio_keys_close;
@@ -774,25 +784,29 @@ static int gpio_keys_probe(struct platform_device *pdev)
input->id.product = 0x0001;
input->id.version = 0x0100;
input->keycode = ddata->keymap;
input->keycodesize = sizeof(ddata->keymap[0]);
input->keycodemax = pdata->nbuttons;
/* Enable auto repeat feature of Linux input subsystem */
if (pdata->rep)
__set_bit(EV_REP, input->evbit);
for (i = 0; i < pdata->nbuttons; i++) {
const struct gpio_keys_button *button = &pdata->buttons[i];
struct gpio_button_data *bdata = &ddata->data[i];
if (!dev_get_platdata(dev)) {
child = device_get_next_child_node(&pdev->dev, child);
child = device_get_next_child_node(dev, child);
if (!child) {
dev_err(&pdev->dev,
dev_err(dev,
"missing child device node for entry %d\n",
i);
return -EINVAL;
}
}
error = gpio_keys_setup_key(pdev, input, bdata, button, child);
error = gpio_keys_setup_key(pdev, input, ddata,
button, i, child);
if (error) {
fwnode_handle_put(child);
return error;
@@ -804,7 +818,7 @@ static int gpio_keys_probe(struct platform_device *pdev)
fwnode_handle_put(child);
error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group);
error = sysfs_create_group(&dev->kobj, &gpio_keys_attr_group);
if (error) {
dev_err(dev, "Unable to export keys/switches, error: %d\n",
error);
@@ -818,12 +832,12 @@ static int gpio_keys_probe(struct platform_device *pdev)
goto err_remove_group;
}
device_init_wakeup(&pdev->dev, wakeup);
device_init_wakeup(dev, wakeup);
return 0;
err_remove_group:
sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
sysfs_remove_group(&dev->kobj, &gpio_keys_attr_group);
return error;
}
@@ -831,8 +845,6 @@ static int gpio_keys_remove(struct platform_device *pdev)
{
sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
device_init_wakeup(&pdev->dev, 0);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More