diff options
96 files changed, 772 insertions, 1137 deletions
diff --git a/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt new file mode 100644 index 000000000000..635f62c756ee --- /dev/null +++ b/Documentation/devicetree/bindings/input/cypress,tm2-touchkey.txt @@ -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>; + }; + }; diff --git a/Documentation/devicetree/bindings/input/mpr121-touchkey.txt b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt new file mode 100644 index 000000000000..b7c61ee5841b --- /dev/null +++ b/Documentation/devicetree/bindings/input/mpr121-touchkey.txt @@ -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>; + }; diff --git a/Documentation/devicetree/bindings/input/pwm-beeper.txt b/Documentation/devicetree/bindings/input/pwm-beeper.txt index be332ae4f2d6..529408b4431a 100644 --- a/Documentation/devicetree/bindings/input/pwm-beeper.txt +++ b/Documentation/devicetree/bindings/input/pwm-beeper.txt @@ -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>; +}; diff --git a/drivers/input/joystick/maplecontrol.c b/drivers/input/joystick/maplecontrol.c index 8aa6e4c497da..ff54e195d42c 100644 --- a/drivers/input/joystick/maplecontrol.c +++ b/drivers/input/joystick/maplecontrol.c @@ -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) diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index c7d5b2b643d1..247fd3a6fc03 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -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 */ { } }; @@ -608,14 +608,28 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha } /* - * xpadone_process_buttons + * xpadone_process_packet + * + * Completes a request by converting the data into events for the + * input subsystem. This version is for the Xbox One controller. * - * Process a button update packet from an 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) { + 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 +692,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 +836,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 +848,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 +868,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) @@ -1468,8 +1448,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,13 +1518,26 @@ 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); - if (error) + 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; + } - /* 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; + error = xpad_init_output(intf, xpad, ep_irq_out); + if (error) + goto err_free_in_urb; usb_fill_int_urb(xpad->irq_in, udev, usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress), diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index cbd75cf44739..97acd6524ad7 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -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 diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index d9f4cfcf3410..7d9acff819a7 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -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 diff --git a/drivers/input/keyboard/adc-keys.c b/drivers/input/keyboard/adc-keys.c index f8cf2ccacefd..c255af21e71a 100644 --- a/drivers/input/keyboard/adc-keys.c +++ b/drivers/input/keyboard/adc-keys.c @@ -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"); diff --git a/drivers/input/keyboard/adp5520-keys.c b/drivers/input/keyboard/adp5520-keys.c index db1004dad108..f0b9b37bde58 100644 --- a/drivers/input/keyboard/adp5520-keys.c +++ b/drivers/input/keyboard/adp5520-keys.c @@ -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; diff --git a/drivers/input/keyboard/bcm-keypad.c b/drivers/input/keyboard/bcm-keypad.c index 86a8b723ae15..2b4e63d81e6d 100644 --- a/drivers/input/keyboard/bcm-keypad.c +++ b/drivers/input/keyboard/bcm-keypad.c @@ -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; diff --git a/drivers/input/keyboard/bf54x-keys.c b/drivers/input/keyboard/bf54x-keys.c index 81b07dddae86..39bcbc38997f 100644 --- a/drivers/input/keyboard/bf54x-keys.c +++ b/drivers/input/keyboard/bf54x-keys.c @@ -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; diff --git a/drivers/input/keyboard/cap11xx.c b/drivers/input/keyboard/cap11xx.c index 4401be225d64..1a1eacae3ea1 100644 --- a/drivers/input/keyboard/cap11xx.c +++ b/drivers/input/keyboard/cap11xx.c @@ -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)) { diff --git a/drivers/input/keyboard/cros_ec_keyb.c b/drivers/input/keyboard/cros_ec_keyb.c index 25943e9bc8bf..87d071ae21da 100644 --- a/drivers/input/keyboard/cros_ec_keyb.c +++ b/drivers/input/keyboard/cros_ec_keyb.c @@ -222,7 +222,7 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) struct device_node *np; int err; - np = pdev->dev.of_node; + np = dev->of_node; if (!np) return -ENODEV; @@ -248,7 +248,6 @@ static int cros_ec_keyb_probe(struct platform_device *pdev) ckdev->ec = ec; ckdev->notifier.notifier_call = cros_ec_keyb_work; ckdev->dev = dev; - dev_set_drvdata(dev, ckdev); idev->name = CROS_EC_DEV_NAME; idev->phys = ec->phys_name; diff --git a/drivers/input/keyboard/davinci_keyscan.c b/drivers/input/keyboard/davinci_keyscan.c index f363d1d2907a..b20a5d044caa 100644 --- a/drivers/input/keyboard/davinci_keyscan.c +++ b/drivers/input/keyboard/davinci_keyscan.c @@ -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; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 582462d0af75..9c92cdf196e3 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -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; } diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index bed4f2086158..4fce43a6a0e0 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -252,13 +252,13 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) size = sizeof(struct gpio_keys_polled_dev) + pdata->nbuttons * sizeof(struct gpio_keys_button_data); - bdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + bdev = devm_kzalloc(dev, size, GFP_KERNEL); if (!bdev) { dev_err(dev, "no memory for private data\n"); return -ENOMEM; } - poll_dev = devm_input_allocate_polled_device(&pdev->dev); + poll_dev = devm_input_allocate_polled_device(dev); if (!poll_dev) { dev_err(dev, "no memory for polled device\n"); return -ENOMEM; @@ -332,7 +332,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) if (button->active_low) flags |= GPIOF_ACTIVE_LOW; - error = devm_gpio_request_one(&pdev->dev, button->gpio, + error = devm_gpio_request_one(dev, button->gpio, flags, button->desc ? : DRV_NAME); if (error) { dev_err(dev, @@ -365,7 +365,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) bdev->poll_dev = poll_dev; bdev->dev = dev; bdev->pdata = pdata; - platform_set_drvdata(pdev, bdev); error = input_register_polled_device(poll_dev); if (error) { diff --git a/drivers/input/keyboard/jornada680_kbd.c b/drivers/input/keyboard/jornada680_kbd.c index 80c81278ad2c..0116ac99f44c 100644 --- a/drivers/input/keyboard/jornada680_kbd.c +++ b/drivers/input/keyboard/jornada680_kbd.c @@ -197,8 +197,6 @@ static int jornada680kbd_probe(struct platform_device *pdev) return -ENOMEM; } - platform_set_drvdata(pdev, jornadakbd); - jornadakbd->poll_dev = poll_dev; memcpy(jornadakbd->keymap, jornada_scancodes, diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 5aa2361aef95..78e3567ec18c 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c @@ -196,7 +196,6 @@ static int probe_maple_kbd(struct device *dev) __clear_bit(KEY_RESERVED, idev->keybit); input_set_capability(idev, EV_MSC, MSC_SCAN); - input_set_drvdata(idev, kbd); error = input_register_device(idev); if (error) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 7f12b6579f82..18839cd5f76e 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -545,8 +545,6 @@ static int matrix_keypad_remove(struct platform_device *pdev) { struct matrix_keypad *keypad = platform_get_drvdata(pdev); - device_init_wakeup(&pdev->dev, 0); - matrix_keypad_free_gpio(keypad); input_unregister_device(keypad->input_dev); kfree(keypad); diff --git a/drivers/input/keyboard/max7359_keypad.c b/drivers/input/keyboard/max7359_keypad.c index 5091133b7b8e..cd44d22d8770 100644 --- a/drivers/input/keyboard/max7359_keypad.c +++ b/drivers/input/keyboard/max7359_keypad.c @@ -241,7 +241,6 @@ static int max7359_probe(struct i2c_client *client, /* Initialize MAX7359 */ max7359_initialize(client); - i2c_set_clientdata(client, keypad); device_init_wakeup(&client->dev, 1); return 0; diff --git a/drivers/input/keyboard/mpr121_touchkey.c b/drivers/input/keyboard/mpr121_touchkey.c index 0fd612dd76ed..884a74d8a7ed 100644 --- a/drivers/input/keyboard/mpr121_touchkey.c +++ b/drivers/input/keyboard/mpr121_touchkey.c @@ -12,14 +12,16 @@ * */ -#include <linux/module.h> -#include <linux/input.h> -#include <linux/i2c.h> -#include <linux/slab.h> -#include <linux/delay.h> #include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/input.h> #include <linux/interrupt.h> -#include <linux/i2c/mpr121_touchkey.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/property.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> /* Register definitions */ #define ELE_TOUCH_STATUS_0_ADDR 0x0 @@ -59,10 +61,9 @@ struct mpr121_touchkey { struct i2c_client *client; struct input_dev *input_dev; - unsigned int key_val; unsigned int statusbits; unsigned int keycount; - u16 keycodes[MPR121_MAX_KEY_COUNT]; + u32 keycodes[MPR121_MAX_KEY_COUNT]; }; struct mpr121_init_register { @@ -82,12 +83,49 @@ static const struct mpr121_init_register init_reg_table[] = { { AUTO_CONFIG_CTRL_ADDR, 0x0b }, }; +static void mpr121_vdd_supply_disable(void *data) +{ + struct regulator *vdd_supply = data; + + regulator_disable(vdd_supply); +} + +static struct regulator *mpr121_vdd_supply_init(struct device *dev) +{ + struct regulator *vdd_supply; + int err; + + vdd_supply = devm_regulator_get(dev, "vdd"); + if (IS_ERR(vdd_supply)) { + dev_err(dev, "failed to get vdd regulator: %ld\n", + PTR_ERR(vdd_supply)); + return vdd_supply; + } + + err = regulator_enable(vdd_supply); + if (err) { + dev_err(dev, "failed to enable vdd regulator: %d\n", err); + return ERR_PTR(err); + } + + err = devm_add_action(dev, mpr121_vdd_supply_disable, vdd_supply); + if (err) { + regulator_disable(vdd_supply); + dev_err(dev, "failed to add disable regulator action: %d\n", + err); + return ERR_PTR(err); + } + + return vdd_supply; +} + static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) { struct mpr121_touchkey *mpr121 = dev_id; struct i2c_client *client = mpr121->client; struct input_dev *input = mpr121->input_dev; - unsigned int key_num, key_val, pressed; + unsigned long bit_changed; + unsigned int key_num; int reg; reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR); @@ -105,26 +143,29 @@ static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id) reg &= TOUCH_STATUS_MASK; /* use old press bit to figure out which bit changed */ - key_num = ffs(reg ^ mpr121->statusbits) - 1; - pressed = reg & (1 << key_num); + bit_changed = reg ^ mpr121->statusbits; mpr121->statusbits = reg; + for_each_set_bit(key_num, &bit_changed, mpr121->keycount) { + unsigned int key_val, pressed; - key_val = mpr121->keycodes[key_num]; + pressed = reg & BIT(key_num); + key_val = mpr121->keycodes[key_num]; - input_event(input, EV_MSC, MSC_SCAN, key_num); - input_report_key(input, key_val, pressed); - input_sync(input); + input_event(input, EV_MSC, MSC_SCAN, key_num); + input_report_key(input, key_val, pressed); - dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, - pressed ? "pressed" : "released"); + dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val, + pressed ? "pressed" : "released"); + + } + input_sync(input); out: return IRQ_HANDLED; } -static int mpr121_phys_init(const struct mpr121_platform_data *pdata, - struct mpr121_touchkey *mpr121, - struct i2c_client *client) +static int mpr121_phys_init(struct mpr121_touchkey *mpr121, + struct i2c_client *client, int vdd_uv) { const struct mpr121_init_register *reg; unsigned char usl, lsl, tl, eleconf; @@ -154,9 +195,9 @@ static int mpr121_phys_init(const struct mpr121_platform_data *pdata, /* * Capacitance on sensing input varies and needs to be compensated. * The internal MPR121-auto-configuration can do this if it's - * registers are set properly (based on pdata->vdd_uv). + * registers are set properly (based on vdd_uv). */ - vdd = pdata->vdd_uv / 1000; + vdd = vdd_uv / 1000; usl = ((vdd - 700) * 256) / vdd; lsl = (usl * 65) / 100; tl = (usl * 90) / 100; @@ -187,72 +228,77 @@ err_i2c_write: static int mpr_touchkey_probe(struct i2c_client *client, const struct i2c_device_id *id) { - const struct mpr121_platform_data *pdata = - dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct regulator *vdd_supply; + int vdd_uv; struct mpr121_touchkey *mpr121; struct input_dev *input_dev; int error; int i; - if (!pdata) { - dev_err(&client->dev, "no platform data defined\n"); - return -EINVAL; - } - - if (!pdata->keymap || !pdata->keymap_size) { - dev_err(&client->dev, "missing keymap data\n"); + if (!client->irq) { + dev_err(dev, "irq number should not be zero\n"); return -EINVAL; } - if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) { - dev_err(&client->dev, "too many keys defined\n"); - return -EINVAL; - } + vdd_supply = mpr121_vdd_supply_init(dev); + if (IS_ERR(vdd_supply)) + return PTR_ERR(vdd_supply); - if (!client->irq) { - dev_err(&client->dev, "irq number should not be zero\n"); - return -EINVAL; - } + vdd_uv = regulator_get_voltage(vdd_supply); - mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121), - GFP_KERNEL); + mpr121 = devm_kzalloc(dev, sizeof(*mpr121), GFP_KERNEL); if (!mpr121) return -ENOMEM; - input_dev = devm_input_allocate_device(&client->dev); + input_dev = devm_input_allocate_device(dev); if (!input_dev) return -ENOMEM; mpr121->client = client; mpr121->input_dev = input_dev; - mpr121->keycount = pdata->keymap_size; + mpr121->keycount = device_property_read_u32_array(dev, "linux,keycodes", + NULL, 0); + if (mpr121->keycount > MPR121_MAX_KEY_COUNT) { + dev_err(dev, "too many keys defined (%d)\n", mpr121->keycount); + return -EINVAL; + } + + error = device_property_read_u32_array(dev, "linux,keycodes", + mpr121->keycodes, + mpr121->keycount); + if (error) { + dev_err(dev, + "failed to read linux,keycode property: %d\n", error); + return error; + } input_dev->name = "Freescale MPR121 Touchkey"; input_dev->id.bustype = BUS_I2C; - input_dev->dev.parent = &client->dev; - input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); + input_dev->dev.parent = dev; + if (device_property_read_bool(dev, "autorepeat")) + __set_bit(EV_REP, input_dev->evbit); + input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_dev->keycode = mpr121->keycodes; input_dev->keycodesize = sizeof(mpr121->keycodes[0]); input_dev->keycodemax = mpr121->keycount; - for (i = 0; i < pdata->keymap_size; i++) { - input_set_capability(input_dev, EV_KEY, pdata->keymap[i]); - mpr121->keycodes[i] = pdata->keymap[i]; - } + for (i = 0; i < mpr121->keycount; i++) + input_set_capability(input_dev, EV_KEY, mpr121->keycodes[i]); - error = mpr121_phys_init(pdata, mpr121, client); + error = mpr121_phys_init(mpr121, client, vdd_uv); if (error) { - dev_err(&client->dev, "Failed to init register\n"); + dev_err(dev, "Failed to init register\n"); return error; } - error = devm_request_threaded_irq(&client->dev, client->irq, NULL, - mpr_touchkey_interrupt, - IRQF_TRIGGER_FALLING | IRQF_ONESHOT, - client->dev.driver->name, mpr121); + 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(&client->dev, "Failed to register interrupt\n"); + dev_err(dev, "Failed to register interrupt\n"); return error; } @@ -261,13 +307,13 @@ static int mpr_touchkey_probe(struct i2c_client *client, return error; i2c_set_clientdata(client, mpr121); - device_init_wakeup(&client->dev, pdata->wakeup); + device_init_wakeup(dev, + device_property_read_bool(dev, "wakeup-source")); return 0; } -#ifdef CONFIG_PM_SLEEP -static int mpr_suspend(struct device *dev) +static int __maybe_unused mpr_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); @@ -279,7 +325,7 @@ static int mpr_suspend(struct device *dev) return 0; } -static int mpr_resume(struct device *dev) +static int __maybe_unused mpr_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client); @@ -292,7 +338,6 @@ static int mpr_resume(struct device *dev) return 0; } -#endif static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume); @@ -302,10 +347,19 @@ static const struct i2c_device_id mpr121_id[] = { }; MODULE_DEVICE_TABLE(i2c, mpr121_id); +#ifdef CONFIG_OF +static const struct of_device_id mpr121_touchkey_dt_match_table[] = { + { .compatible = "fsl,mpr121-touchkey" }, + { }, +}; +MODULE_DEVICE_TABLE(of, mpr121_touchkey_dt_match_table); +#endif + static struct i2c_driver mpr_touchkey_driver = { .driver = { .name = "mpr121", .pm = &mpr121_touchkey_pm_ops, + .of_match_table = of_match_ptr(mpr121_touchkey_dt_match_table), }, .id_table = mpr121_id, .probe = mpr_touchkey_probe, diff --git a/drivers/input/keyboard/nspire-keypad.c b/drivers/input/keyboard/nspire-keypad.c index 7abfd34eb87e..c7f26fa3034c 100644 --- a/drivers/input/keyboard/nspire-keypad.c +++ b/drivers/input/keyboard/nspire-keypad.c @@ -249,8 +249,6 @@ static int nspire_keypad_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, keypad); - dev_dbg(&pdev->dev, "TI-NSPIRE keypad at %pR (scan_interval=%uus, row_delay=%uus%s)\n", res, keypad->row_delay, keypad->scan_interval, diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index 6639b2b8528a..9ecb16701b13 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -375,7 +375,6 @@ static int omap4_keypad_probe(struct platform_device *pdev) err_pm_disable: pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, false); free_irq(keypad_data->irq, keypad_data); err_free_keymap: kfree(keypad_data->keymap); @@ -401,8 +400,6 @@ static int omap4_keypad_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, false); - input_unregister_device(keypad_data->input); iounmap(keypad_data->base); diff --git a/drivers/input/keyboard/opencores-kbd.c b/drivers/input/keyboard/opencores-kbd.c index f8502bb29176..d62b4068c077 100644 --- a/drivers/input/keyboard/opencores-kbd.c +++ b/drivers/input/keyboard/opencores-kbd.c @@ -75,8 +75,6 @@ static int opencores_kbd_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = "opencores-kbd/input0"; - input_set_drvdata(input, opencores_kbd); - input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; input->id.product = 0x0001; @@ -112,8 +110,6 @@ static int opencores_kbd_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, opencores_kbd); - return 0; } diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index 4e319eb9e19d..316414465c77 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -445,7 +445,6 @@ static int samsung_keypad_probe(struct platform_device *pdev) err_disable_runtime_pm: pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, 0); err_unprepare_clk: clk_unprepare(keypad->clk); return error; @@ -456,7 +455,6 @@ static int samsung_keypad_remove(struct platform_device *pdev) struct samsung_keypad *keypad = platform_get_drvdata(pdev); pm_runtime_disable(&pdev->dev); - device_init_wakeup(&pdev->dev, 0); input_unregister_device(keypad->input_dev); diff --git a/drivers/input/keyboard/spear-keyboard.c b/drivers/input/keyboard/spear-keyboard.c index 8083eaa0524a..7d25fa338ab4 100644 --- a/drivers/input/keyboard/spear-keyboard.c +++ b/drivers/input/keyboard/spear-keyboard.c @@ -283,8 +283,6 @@ static int spear_kbd_remove(struct platform_device *pdev) input_unregister_device(kbd->input); clk_unprepare(kbd->clk); - device_init_wakeup(&pdev->dev, 0); - return 0; } diff --git a/drivers/input/keyboard/sun4i-lradc-keys.c b/drivers/input/keyboard/sun4i-lradc-keys.c index cc8f7ddcee53..a37c172452e6 100644 --- a/drivers/input/keyboard/sun4i-lradc-keys.c +++ b/drivers/input/keyboard/sun4i-lradc-keys.c @@ -261,7 +261,6 @@ static int sun4i_lradc_probe(struct platform_device *pdev) if (error) return error; - platform_set_drvdata(pdev, lradc); return 0; } diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 3048ef3e3e16..9f6308fac0b4 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c @@ -277,6 +277,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, bool irq_is_gpio = false; int irq; int error, row_shift, max_keys; + unsigned long trigger = 0; /* Copy the platform data */ if (pdata) { @@ -289,6 +290,7 @@ static int tca8418_keypad_probe(struct i2c_client *client, cols = pdata->cols; rep = pdata->rep; irq_is_gpio = pdata->irq_is_gpio; + trigger = IRQF_TRIGGER_FALLING; } else { struct device_node *np = dev->of_node; int err; @@ -356,16 +358,12 @@ static int tca8418_keypad_probe(struct i2c_client *client, __set_bit(EV_REP, input->evbit); input_set_capability(input, EV_MSC, MSC_SCAN); - input_set_drvdata(input, keypad_data); - irq = client->irq; if (irq_is_gpio) irq = gpio_to_irq(irq); error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, - IRQF_TRIGGER_FALLING | - IRQF_SHARED | - IRQF_ONESHOT, + trigger | IRQF_SHARED | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c new file mode 100644 index 000000000000..485900f953e0 --- /dev/null +++ b/drivers/input/keyboard/tm2-touchkey.c @@ -0,0 +1,284 @@ +/* + * TM2 touchkey device driver + * + * Copyright 2005 Phil Blundell + * Copyright 2016 Samsung Electronics Co., Ltd. + * + * Author: Beomho Seo <[email protected]> + * Author: Jaechul Lee <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/bitops.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/i2c.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/leds.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pm.h> +#include <linux/regulator/consumer.h> + +#define TM2_TOUCHKEY_DEV_NAME "tm2-touchkey" +#define TM2_TOUCHKEY_KEYCODE_REG 0x03 +#define TM2_TOUCHKEY_BASE_REG 0x00 +#define TM2_TOUCHKEY_CMD_LED_ON 0x10 +#define TM2_TOUCHKEY_CMD_LED_OFF 0x20 +#define TM2_TOUCHKEY_BIT_PRESS_EV BIT(3) +#define TM2_TOUCHKEY_BIT_KEYCODE GENMASK(2, 0) +#define TM2_TOUCHKEY_LED_VOLTAGE_MIN 2500000 +#define TM2_TOUCHKEY_LED_VOLTAGE_MAX 3300000 + +enum { + TM2_TOUCHKEY_KEY_MENU = 0x1, + TM2_TOUCHKEY_KEY_BACK, +}; + +struct tm2_touchkey_data { + struct i2c_client *client; + struct input_dev *input_dev; + struct led_classdev led_dev; + struct regulator *vdd; + struct regulator_bulk_data regulators[2]; +}; + +static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev, + enum led_brightness brightness) +{ + struct tm2_touchkey_data *touchkey = + container_of(led_dev, struct tm2_touchkey_data, led_dev); + u32 volt; + u8 data; + + if (brightness == LED_OFF) { + volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN; + data = TM2_TOUCHKEY_CMD_LED_OFF; + } else { + volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX; + data = TM2_TOUCHKEY_CMD_LED_ON; + } + + regulator_set_voltage(touchkey->vdd, volt, volt); + i2c_smbus_write_byte_data(touchkey->client, + TM2_TOUCHKEY_BASE_REG, data); +} + +static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey) +{ + int error; + + error = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if (error) + return error; + + /* waiting for device initialization, at least 150ms */ + msleep(150); + + return 0; +} + +static void tm2_touchkey_power_disable(void *data) +{ + struct tm2_touchkey_data *touchkey = data; + + regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); +} + +static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid) +{ + struct tm2_touchkey_data *touchkey = devid; + int data; + int key; + + data = i2c_smbus_read_byte_data(touchkey->client, + TM2_TOUCHKEY_KEYCODE_REG); + if (data < 0) { + dev_err(&touchkey->client->dev, + "failed to read i2c data: %d\n", data); + goto out; + } + + switch (data & TM2_TOUCHKEY_BIT_KEYCODE) { + case TM2_TOUCHKEY_KEY_MENU: + key = KEY_PHONE; + break; + + case TM2_TOUCHKEY_KEY_BACK: + key = KEY_BACK; + break; + + default: + dev_warn(&touchkey->client->dev, + "unhandled keycode, data %#02x\n", data); + goto out; + } + + if (data & TM2_TOUCHKEY_BIT_PRESS_EV) { + input_report_key(touchkey->input_dev, KEY_PHONE, 0); + input_report_key(touchkey->input_dev, KEY_BACK, 0); + } else { + input_report_key(touchkey->input_dev, key, 1); + } + + input_sync(touchkey->input_dev); + +out: + return IRQ_HANDLED; +} + +static int tm2_touchkey_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tm2_touchkey_data *touchkey; + int error; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "incompatible I2C adapter\n"); + return -EIO; + } + + touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL); + if (!touchkey) + return -ENOMEM; + + touchkey->client = client; + i2c_set_clientdata(client, touchkey); + + touchkey->regulators[0].supply = "vcc"; + touchkey->regulators[1].supply = "vdd"; + error = devm_regulator_bulk_get(&client->dev, + ARRAY_SIZE(touchkey->regulators), + touchkey->regulators); + if (error) { + dev_err(&client->dev, "failed to get regulators: %d\n", error); + return error; + } + + /* Save VDD for easy access */ + touchkey->vdd = touchkey->regulators[1].consumer; + + error = tm2_touchkey_power_enable(touchkey); + if (error) { + dev_err(&client->dev, "failed to power up device: %d\n", error); + return error; + } + + error = devm_add_action_or_reset(&client->dev, + tm2_touchkey_power_disable, touchkey); + if (error) { + dev_err(&client->dev, + "failed to install poweroff handler: %d\n", error); + return error; + } + + /* input device */ + touchkey->input_dev = devm_input_allocate_device(&client->dev); + if (!touchkey->input_dev) { + dev_err(&client->dev, "failed to allocate input device\n"); + return -ENOMEM; + } + + touchkey->input_dev->name = TM2_TOUCHKEY_DEV_NAME; + touchkey->input_dev->id.bustype = BUS_I2C; + + input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE); + input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK); + + error = input_register_device(touchkey->input_dev); + if (error) { + dev_err(&client->dev, + "failed to register input device: %d\n", error); + return error; + } + + error = devm_request_threaded_irq(&client->dev, client->irq, + NULL, tm2_touchkey_irq_handler, + IRQF_ONESHOT, + TM2_TOUCHKEY_DEV_NAME, touchkey); + if (error) { + dev_err(&client->dev, + "failed to request threaded irq: %d\n", error); + return error; + } + + /* led device */ + touchkey->led_dev.name = TM2_TOUCHKEY_DEV_NAME; + touchkey->led_dev.brightness = LED_FULL; + touchkey->led_dev.max_brightness = LED_FULL; + touchkey->led_dev.brightness_set = tm2_touchkey_led_brightness_set; + + error = devm_led_classdev_register(&client->dev, &touchkey->led_dev); + if (error) { + dev_err(&client->dev, + "failed to register touchkey led: %d\n", error); + return error; + } + + return 0; +} + +static int __maybe_unused tm2_touchkey_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client); + + disable_irq(client->irq); + tm2_touchkey_power_disable(touchkey); + + return 0; +} + +static int __maybe_unused tm2_touchkey_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct tm2_touchkey_data *touchkey = i2c_get_clientdata(client); + int ret; + + enable_irq(client->irq); + + ret = tm2_touchkey_power_enable(touchkey); + if (ret) + dev_err(dev, "failed to enable power: %d\n", ret); + + return ret; +} + +static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops, + tm2_touchkey_suspend, tm2_touchkey_resume); + +static const struct i2c_device_id tm2_touchkey_id_table[] = { + { TM2_TOUCHKEY_DEV_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table); + +static const struct of_device_id tm2_touchkey_of_match[] = { + { .compatible = "cypress,tm2-touchkey", }, + { }, +}; +MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match); + +static struct i2c_driver tm2_touchkey_driver = { + .driver = { + .name = TM2_TOUCHKEY_DEV_NAME, + .pm = &tm2_touchkey_pm_ops, + .of_match_table = of_match_ptr(tm2_touchkey_of_match), + }, + .probe = tm2_touchkey_probe, + .id_table = tm2_touchkey_id_table, +}; +module_i2c_driver(tm2_touchkey_driver); + +MODULE_AUTHOR("Beomho Seo <[email protected]>"); +MODULE_AUTHOR("Jaechul Lee <[email protected]>"); +MODULE_DESCRIPTION("Samsung touchkey driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 323a0fb575a4..29396ca69416 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -441,7 +441,6 @@ static int twl4030_kp_probe(struct platform_device *pdev) return -EIO; } - platform_set_drvdata(pdev, kp); return 0; } diff --git a/drivers/input/misc/88pm80x_onkey.c b/drivers/input/misc/88pm80x_onkey.c index cf9908f1e5d5..45a09497f680 100644 --- a/drivers/input/misc/88pm80x_onkey.c +++ b/drivers/input/misc/88pm80x_onkey.c @@ -143,7 +143,6 @@ static int pm80x_onkey_remove(struct platform_device *pdev) { struct pm80x_onkey_info *info = platform_get_drvdata(pdev); - device_init_wakeup(&pdev->dev, 0); pm80x_free_irq(info->pm80x, info->irq, info); input_unregister_device(info->idev); kfree(info); diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c index 4f5ef5bb535b..a33ed5710b15 100644 --- a/drivers/input/misc/ab8500-ponkey.c +++ b/drivers/input/misc/ab8500-ponkey.c @@ -109,7 +109,6 @@ static int ab8500_ponkey_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, ponkey); return 0; } diff --git a/drivers/input/misc/arizona-haptics.c b/drivers/input/misc/arizona-haptics.c index 07ec465f1095..21dc1b8b2a4a 100644 --- a/drivers/input/misc/arizona-haptics.c +++ b/drivers/input/misc/arizona-haptics.c @@ -201,8 +201,6 @@ static int arizona_haptics_probe(struct platform_device *pdev) return ret; } - platform_set_drvdata(pdev, haptics); - return 0; } diff --git a/drivers/input/misc/atmel_captouch.c b/drivers/input/misc/atmel_captouch.c index 941265415a89..c4c0f4bb7627 100644 --- a/drivers/input/misc/atmel_captouch.c +++ b/drivers/input/misc/atmel_captouch.c @@ -191,7 +191,6 @@ static int atmel_captouch_probe(struct i2c_client *client, return -ENOMEM; capdev->client = client; - i2c_set_clientdata(client, capdev); err = atmel_read(capdev, REG_KEY_STATE, &capdev->prev_btn, sizeof(capdev->prev_btn)); diff --git a/drivers/input/misc/bfin_rotary.c b/drivers/input/misc/bfin_rotary.c index a0fc18fdfc0c..799ce3d2820e 100644 --- a/drivers/input/misc/bfin_rotary.c +++ b/drivers/input/misc/bfin_rotary.c @@ -147,19 +147,18 @@ static int bfin_rotary_probe(struct platform_device *pdev) if (pdata->pin_list) { error = peripheral_request_list(pdata->pin_list, - dev_name(&pdev->dev)); + dev_name(dev)); if (error) { dev_err(dev, "requesting peripherals failed: %d\n", error); return error; } - error = devm_add_action(dev, bfin_rotary_free_action, - pdata->pin_list); + error = devm_add_action_or_reset(dev, bfin_rotary_free_action, + pdata->pin_list); if (error) { dev_err(dev, "setting cleanup action failed: %d\n", error); - peripheral_free_list(pdata->pin_list); return error; } } @@ -189,7 +188,7 @@ static int bfin_rotary_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = "bfin-rotary/input0"; - input->dev.parent = &pdev->dev; + input->dev.parent = dev; input_set_drvdata(input, rotary); @@ -239,7 +238,7 @@ static int bfin_rotary_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, rotary); - device_init_wakeup(&pdev->dev, 1); + device_init_wakeup(dev, 1); return 0; } diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c index 2124390ec38c..1fa85379f86c 100644 --- a/drivers/input/misc/bma150.c +++ b/drivers/input/misc/bma150.c @@ -207,7 +207,7 @@ static int bma150_set_mode(struct bma150_data *bma150, u8 mode) return error; if (mode == BMA150_MODE_NORMAL) - msleep(2); + usleep_range(2000, 2100); bma150->mode = mode; return 0; @@ -222,7 +222,7 @@ static int bma150_soft_reset(struct bma150_data *bma150) if (error) return error; - msleep(2); + usleep_range(2000, 2100); return 0; } diff --git a/drivers/input/misc/da9063_onkey.c b/drivers/input/misc/da9063_onkey.c index b4ff1e86d3d3..3e9c353d82ef 100644 --- a/drivers/input/misc/da9063_onkey.c +++ b/drivers/input/misc/da9063_onkey.c @@ -287,7 +287,6 @@ static int da9063_onkey_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, onkey); return 0; } diff --git a/drivers/input/misc/dm355evm_keys.c b/drivers/input/misc/dm355evm_keys.c index b6b7bd4e5462..82e272ebc0ed 100644 --- a/drivers/input/misc/dm355evm_keys.c +++ b/drivers/input/misc/dm355evm_keys.c @@ -195,8 +195,6 @@ static int dm355evm_keys_probe(struct platform_device *pdev) goto fail1; keys->irq = status; - input_set_drvdata(input, keys); - input->name = "DM355 EVM Controls"; input->phys = "dm355evm/input0"; input->dev.parent = &pdev->dev; diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c index 0a2b865b1000..fb089d36c0d6 100644 --- a/drivers/input/misc/drv260x.c +++ b/drivers/input/misc/drv260x.c @@ -538,7 +538,7 @@ static int drv260x_probe(struct i2c_client *client, haptics->input_dev = devm_input_allocate_device(dev); if (!haptics->input_dev) { - dev_err(&client->dev, "Failed to allocate input device\n"); + dev_err(dev, "Failed to allocate input device\n"); return -ENOMEM; } diff --git a/drivers/input/misc/e3x0-button.c b/drivers/input/misc/e3x0-button.c index 13bfca8a7b16..e956cf1d273f 100644 --- a/drivers/input/misc/e3x0-button.c +++ b/drivers/input/misc/e3x0-button.c @@ -120,17 +120,10 @@ static int e3x0_button_probe(struct platform_device *pdev) return error; } - platform_set_drvdata(pdev, input); device_init_wakeup(&pdev->dev, 1); return 0; } -static int e3x0_button_remove(struct platform_device *pdev) -{ - device_init_wakeup(&pdev->dev, 0); - return 0; -} - #ifdef CONFIG_OF static const struct of_device_id e3x0_button_match[] = { { .compatible = "ettus,e3x0-button", }, @@ -146,7 +139,6 @@ static struct platform_driver e3x0_button_driver = { .pm = &e3x0_button_pm_ops, }, .probe = e3x0_button_probe, - .remove = e3x0_button_remove, }; module_platform_driver(e3x0_button_driver); diff --git a/drivers/input/misc/gp2ap002a00f.c b/drivers/input/misc/gp2ap002a00f.c index 3bfdfcc20485..c6a29e57b5e4 100644 --- a/drivers/input/misc/gp2ap002a00f.c +++ b/drivers/input/misc/gp2ap002a00f.c @@ -210,8 +210,6 @@ static int gp2a_remove(struct i2c_client *client) struct gp2a_data *dt = i2c_get_clientdata(client); const struct gp2a_platform_data *pdata = dt->pdata; - device_init_wakeup(&client->dev, false); - free_irq(client->irq, dt); input_unregister_device(dt->input); diff --git a/drivers/input/misc/gpio_decoder.c b/drivers/input/misc/gpio_decoder.c index ca7e0bacb2d8..1dca526e6f1a 100644 --- a/drivers/input/misc/gpio_decoder.c +++ b/drivers/input/misc/gpio_decoder.c @@ -110,7 +110,6 @@ static int gpio_decoder_probe(struct platform_device *pdev) dev_err(dev, "failed to register polled device\n"); return err; } - platform_set_drvdata(pdev, decoder); return 0; } diff --git a/drivers/input/misc/gpio_tilt_polled.c b/drivers/input/misc/gpio_tilt_polled.c index f103b99d1852..6e217a45e39a 100644 --- a/drivers/input/misc/gpio_tilt_polled.c +++ b/drivers/input/misc/gpio_tilt_polled.c @@ -138,7 +138,7 @@ static int gpio_tilt_polled_probe(struct platform_device *pdev) input->name = pdev->name; input->phys = DRV_NAME"/input0"; - input->dev.parent = &pdev->dev; + input->dev.parent = dev; input->id.bustype = BUS_HOST; input->id.vendor = 0x0001; diff --git a/drivers/input/misc/hisi_powerkey.c b/drivers/input/misc/hisi_powerkey.c index 675539c529ce..dee6245f38d7 100644 --- a/drivers/input/misc/hisi_powerkey.c +++ b/drivers/input/misc/hisi_powerkey.c @@ -75,9 +75,9 @@ static int hi65xx_powerkey_probe(struct platform_device *pdev) struct input_dev *input; int irq, i, error; - input = devm_input_allocate_device(&pdev->dev); + input = devm_input_allocate_device(dev); if (!input) { - dev_err(&pdev->dev, "failed to allocate input device\n"); + dev_err(dev, "failed to allocate input device\n"); return -ENOMEM; } @@ -111,19 +111,11 @@ static int hi65xx_powerkey_probe(struct platform_device *pdev) error = input_register_device(input); if (error) { - dev_err(&pdev->dev, "failed to register input device: %d\n", - error); + dev_err(dev, "failed to register input device: %d\n", error); return error; } - device_init_wakeup(&pdev->dev, 1); - - return 0; -} - -static int hi65xx_powerkey_remove(struct platform_device *pdev) -{ - device_init_wakeup(&pdev->dev, 0); + device_init_wakeup(dev, 1); return 0; } @@ -133,7 +125,6 @@ static struct platform_driver hi65xx_powerkey_driver = { .name = "hi65xx-powerkey", }, .probe = hi65xx_powerkey_probe, - .remove = hi65xx_powerkey_remove, }; module_platform_driver(hi65xx_powerkey_driver); diff --git a/drivers/input/misc/mma8450.c b/drivers/input/misc/mma8450.c index 19c73574458e..b60cdea73826 100644 --- a/drivers/input/misc/mma8450.c +++ b/drivers/input/misc/mma8450.c @@ -205,8 +205,6 @@ static int mma8450_probe(struct i2c_client *c, return err; } - i2c_set_clientdata(c, m); - return 0; } diff --git a/drivers/input/misc/pm8941-pwrkey.c b/drivers/input/misc/pm8941-pwrkey.c index e317b75357a0..18ad956454f1 100644 --- a/drivers/input/misc/pm8941-pwrkey.c +++ b/drivers/input/misc/pm8941-pwrkey.c @@ -266,7 +266,6 @@ static int pm8941_pwrkey_remove(struct platform_device *pdev) { struct pm8941_pwrkey *pwrkey = platform_get_drvdata(pdev); - device_init_wakeup(&pdev->dev, 0); unregister_reboot_notifier(&pwrkey->reboot_notifier); return 0; diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index 67aab86048ad..73323b0c72c1 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c @@ -438,13 +438,6 @@ static int pmic8xxx_pwrkey_probe(struct platform_device *pdev) return 0; } -static int pmic8xxx_pwrkey_remove(struct platform_device *pdev) -{ - device_init_wakeup(&pdev->dev, 0); - - return 0; -} - static const struct of_device_id pm8xxx_pwr_key_id_table[] = { { .compatible = "qcom,pm8058-pwrkey", .data = &pm8058_pwrkey_shutdown }, { .compatible = "qcom,pm8921-pwrkey", .data = &pm8921_pwrkey_shutdown }, @@ -454,7 +447,6 @@ MODULE_DEVICE_TABLE(of, pm8xxx_pwr_key_id_table); static struct platform_driver pmic8xxx_pwrkey_driver = { .probe = pmic8xxx_pwrkey_probe, - .remove = pmic8xxx_pwrkey_remove, .shutdown = pmic8xxx_pwrkey_shutdown, .driver = { .name = "pm8xxx-pwrkey", diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c index 5f9655d49a65..e53801dbd560 100644 --- a/drivers/input/misc/pwm-beeper.c +++ b/drivers/input/misc/pwm-beeper.c @@ -14,6 +14,7 @@ */ #include <linux/input.h> +#include <linux/regulator/consumer.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/of.h> @@ -25,29 +26,62 @@ struct pwm_beeper { struct input_dev *input; struct pwm_device *pwm; + struct regulator *amplifier; struct work_struct work; unsigned long period; + bool suspended; + bool amplifier_on; }; #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x)) -static void __pwm_beeper_set(struct pwm_beeper *beeper) +static int pwm_beeper_on(struct pwm_beeper *beeper, unsigned long period) { - unsigned long period = beeper->period; + struct pwm_state state; + int error; + + pwm_get_state(beeper->pwm, &state); + + state.enabled = true; + state.period = period; + pwm_set_relative_duty_cycle(&state, 50, 100); + + error = pwm_apply_state(beeper->pwm, &state); + if (error) + return error; + + if (!beeper->amplifier_on) { + error = regulator_enable(beeper->amplifier); + if (error) { + pwm_disable(beeper->pwm); + return error; + } + + beeper->amplifier_on = true; + } + + return 0; +} - if (period) { - pwm_config(beeper->pwm, period / 2, period); - pwm_enable(beeper->pwm); - } else - pwm_disable(beeper->pwm); +static void pwm_beeper_off(struct pwm_beeper *beeper) +{ + if (beeper->amplifier_on) { + regulator_disable(beeper->amplifier); + beeper->amplifier_on = false; + } + + pwm_disable(beeper->pwm); } static void pwm_beeper_work(struct work_struct *work) { - struct pwm_beeper *beeper = - container_of(work, struct pwm_beeper, work); + struct pwm_beeper *beeper = container_of(work, struct pwm_beeper, work); + unsigned long period = READ_ONCE(beeper->period); - __pwm_beeper_set(beeper); + if (period) + pwm_beeper_on(beeper, period); + else + pwm_beeper_off(beeper); } static int pwm_beeper_event(struct input_dev *input, @@ -73,7 +107,8 @@ static int pwm_beeper_event(struct input_dev *input, else beeper->period = HZ_TO_NANOSECONDS(value); - schedule_work(&beeper->work); + if (!beeper->suspended) + schedule_work(&beeper->work); return 0; } @@ -81,9 +116,7 @@ static int pwm_beeper_event(struct input_dev *input, static void pwm_beeper_stop(struct pwm_beeper *beeper) { cancel_work_sync(&beeper->work); - - if (beeper->period) - pwm_disable(beeper->pwm); + pwm_beeper_off(beeper); } static void pwm_beeper_close(struct input_dev *input) @@ -95,41 +128,50 @@ static void pwm_beeper_close(struct input_dev *input) static int pwm_beeper_probe(struct platform_device *pdev) { - unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev); + struct device *dev = &pdev->dev; struct pwm_beeper *beeper; + struct pwm_state state; int error; - beeper = kzalloc(sizeof(*beeper), GFP_KERNEL); + beeper = devm_kzalloc(dev, sizeof(*beeper), GFP_KERNEL); if (!beeper) return -ENOMEM; - beeper->pwm = pwm_get(&pdev->dev, NULL); + beeper->pwm = devm_pwm_get(dev, NULL); if (IS_ERR(beeper->pwm)) { - dev_dbg(&pdev->dev, "unable to request PWM, trying legacy API\n"); - beeper->pwm = pwm_request(pwm_id, "pwm beeper"); + error = PTR_ERR(beeper->pwm); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to request PWM device: %d\n", + error); + return error; } - if (IS_ERR(beeper->pwm)) { - error = PTR_ERR(beeper->pwm); - dev_err(&pdev->dev, "Failed to request pwm device: %d\n", error); - goto err_free; + /* Sync up PWM state and ensure it is off. */ + pwm_init_state(beeper->pwm, &state); + state.enabled = false; + error = pwm_apply_state(beeper->pwm, &state); + if (error) { + dev_err(dev, "failed to apply initial PWM state: %d\n", + error); + return error; } - /* - * FIXME: pwm_apply_args() should be removed when switching to - * the atomic PWM API. - */ - pwm_apply_args(beeper->pwm); + beeper->amplifier = devm_regulator_get(dev, "amp"); + if (IS_ERR(beeper->amplifier)) { + error = PTR_ERR(beeper->amplifier); + if (error != -EPROBE_DEFER) + dev_err(dev, "Failed to get 'amp' regulator: %d\n", + error); + return error; + } INIT_WORK(&beeper->work, pwm_beeper_work); - beeper->input = input_allocate_device(); + beeper->input = devm_input_allocate_device(dev); if (!beeper->input) { - dev_err(&pdev->dev, "Failed to allocate input device\n"); - error = -ENOMEM; - goto err_pwm_free; + dev_err(dev, "Failed to allocate input device\n"); + return -ENOMEM; } - beeper->input->dev.parent = &pdev->dev; beeper->input->name = "pwm-beeper"; beeper->input->phys = "pwm/input0"; @@ -138,8 +180,8 @@ static int pwm_beeper_probe(struct platform_device *pdev) beeper->input->id.product = 0x0001; beeper->input->id.version = 0x0100; - beeper->input->evbit[0] = BIT(EV_SND); - beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL); + input_set_capability(beeper->input, EV_SND, SND_TONE); + input_set_capability(beeper->input, EV_SND, SND_BELL); beeper->input->event = pwm_beeper_event; beeper->input->close = pwm_beeper_close; @@ -148,41 +190,28 @@ static int pwm_beeper_probe(struct platform_device *pdev) error = input_register_device(beeper->input); if (error) { - dev_err(&pdev->dev, "Failed to register input device: %d\n", error); - goto err_input_free; + dev_err(dev, "Failed to register input device: %d\n", error); + return error; } platform_set_drvdata(pdev, beeper); return 0; - -err_input_free: - input_free_device(beeper->input); -err_pwm_free: - pwm_free(beeper->pwm); -err_free: - kfree(beeper); - - return error; -} - -static int pwm_beeper_remove(struct platform_device *pdev) -{ - struct pwm_beeper *beeper = platform_get_drvdata(pdev); - - input_unregister_device(beeper->input); - - pwm_free(beeper->pwm); - - kfree(beeper); - - return 0; } static int __maybe_unused pwm_beeper_suspend(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); + /* + * Spinlock is taken here is not to protect write to + * beeper->suspended, but to ensure that pwm_beeper_event + * does not re-submit work once flag is set. + */ + spin_lock_irq(&beeper->input->event_lock); + beeper->suspended = true; + spin_unlock_irq(&beeper->input->event_lock); + pwm_beeper_stop(beeper); return 0; @@ -192,8 +221,12 @@ static int __maybe_unused pwm_beeper_resume(struct device *dev) { struct pwm_beeper *beeper = dev_get_drvdata(dev); - if (beeper->period) - __pwm_beeper_set(beeper); + spin_lock_irq(&beeper->input->event_lock); + beeper->suspended = false; + spin_unlock_irq(&beeper->input->event_lock); + + /* Let worker figure out if we should resume beeping */ + schedule_work(&beeper->work); return 0; } @@ -211,7 +244,6 @@ MODULE_DEVICE_TABLE(of, pwm_beeper_match); static struct platform_driver pwm_beeper_driver = { .probe = pwm_beeper_probe, - .remove = pwm_beeper_remove, .driver = { .name = "pwm-beeper", .pm = &pwm_beeper_pm_ops, diff --git a/drivers/input/misc/retu-pwrbutton.c b/drivers/input/misc/retu-pwrbutton.c index 30b459b6b344..64023ac08e2b 100644 --- a/drivers/input/misc/retu-pwrbutton.c +++ b/drivers/input/misc/retu-pwrbutton.c @@ -76,14 +76,8 @@ static int retu_pwrbutton_probe(struct platform_device *pdev) return 0; } -static int retu_pwrbutton_remove(struct platform_device *pdev) -{ - return 0; -} - static struct platform_driver retu_pwrbutton_driver = { .probe = retu_pwrbutton_probe, - .remove = retu_pwrbutton_remove, .driver = { .name = "retu-pwrbutton", }, diff --git a/drivers/input/misc/sirfsoc-onkey.c b/drivers/input/misc/sirfsoc-onkey.c index ed7237f19539..4fd038d476a3 100644 --- a/drivers/input/misc/sirfsoc-onkey.c +++ b/drivers/input/misc/sirfsoc-onkey.c @@ -172,13 +172,6 @@ static int sirfsoc_pwrc_probe(struct platform_device *pdev) return 0; } -static int sirfsoc_pwrc_remove(struct platform_device *pdev) -{ - device_init_wakeup(&pdev->dev, 0); - - return 0; -} - static int __maybe_unused sirfsoc_pwrc_resume(struct device *dev) { struct sirfsoc_pwrc_drvdata *pwrcdrv = dev_get_drvdata(dev); @@ -200,7 +193,6 @@ static SIMPLE_DEV_PM_OPS(sirfsoc_pwrc_pm_ops, NULL, sirfsoc_pwrc_resume); static struct platform_driver sirfsoc_pwrc_driver = { .probe = sirfsoc_pwrc_probe, - .remove = sirfsoc_pwrc_remove, .driver = { .name = "sirfsoc-pwrc", .pm = &sirfsoc_pwrc_pm_ops, diff --git a/drivers/input/misc/soc_button_array.c b/drivers/input/misc/soc_button_array.c index 908b51089dee..ddb2f22fca7a 100644 --- a/drivers/input/misc/soc_button_array.c +++ b/drivers/input/misc/soc_button_array.c @@ -102,6 +102,8 @@ soc_button_device_create(struct platform_device *pdev, gpio_keys[n_buttons].active_low = 1; gpio_keys[n_buttons].desc = info->name; gpio_keys[n_buttons].wakeup = info->wakeup; + /* These devices often use cheap buttons, use 50 ms debounce */ + gpio_keys[n_buttons].debounce_interval = 50; n_buttons++; } @@ -167,12 +169,12 @@ static int soc_button_probe(struct platform_device *pdev) button_info = (struct soc_button_info *)id->driver_data; - if (gpiod_count(&pdev->dev, KBUILD_MODNAME) <= 0) { - dev_dbg(&pdev->dev, "no GPIO attached, ignoring...\n"); + if (gpiod_count(dev, KBUILD_MODNAME) <= 0) { + dev_dbg(dev, "no GPIO attached, ignoring...\n"); return -ENODEV; } - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/input/misc/tps65218-pwrbutton.c b/drivers/input/misc/tps65218-pwrbutton.c index cc74a41bdb0d..a4455bb12ae0 100644 --- a/drivers/input/misc/tps65218-pwrbutton.c +++ b/drivers/input/misc/tps65218-pwrbutton.c @@ -95,7 +95,7 @@ static int tps6521x_pb_probe(struct platform_device *pdev) int error; int irq; - match = of_match_node(of_tps6521x_pb_match, pdev->dev.of_node); + match = of_match_node(of_tps6521x_pb_match, dev->of_node); if (!match) return -ENXIO; @@ -118,10 +118,9 @@ static int tps6521x_pb_probe(struct platform_device *pdev) input_set_capability(idev, EV_KEY, KEY_POWER); - pwr->regmap = dev_get_regmap(pdev->dev.parent, NULL); + pwr->regmap = dev_get_regmap(dev->parent, NULL); pwr->dev = dev; pwr->idev = idev; - platform_set_drvdata(pdev, pwr); device_init_wakeup(dev, true); irq = platform_get_irq(pdev, 0); @@ -136,8 +135,7 @@ static int tps6521x_pb_probe(struct platform_device *pdev) IRQF_ONESHOT, pwr->data->name, pwr); if (error) { - dev_err(dev, "failed to request IRQ #%d: %d\n", - irq, error); + dev_err(dev, "failed to request IRQ #%d: %d\n", irq, error); return error; } diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index 603fc2fadf05..54162d2cbcfc 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -85,7 +85,6 @@ static int twl4030_pwrbutton_probe(struct platform_device *pdev) return err; } - platform_set_drvdata(pdev, pwr); device_init_wakeup(&pdev->dev, true); return 0; diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 328edc8c8786..72b28ebfe360 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -1855,7 +1855,7 @@ static int alps_absolute_mode_v1_v2(struct psmouse *psmouse) * Switch mouse to poll (remote) mode so motion data will not * get in our way */ - return ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETPOLL); + return ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETPOLL); } static int alps_monitor_mode_send_word(struct psmouse *psmouse, u16 word) diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 30e3442518f8..d0122134f320 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -665,7 +665,7 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) char *data; /* Type 3 does not require a mode switch */ - if (dev->cfg.tp_type == TYPE3) + if (c->tp_type == TYPE3) return 0; data = kmalloc(c->um_size, GFP_KERNEL); diff --git a/drivers/input/mouse/cyapa.c b/drivers/input/mouse/cyapa.c index dc2394292088..fd8865c65caf 100644 --- a/drivers/input/mouse/cyapa.c +++ b/drivers/input/mouse/cyapa.c @@ -832,8 +832,8 @@ static int cyapa_prepare_wakeup_controls(struct cyapa *cyapa) int error; if (device_can_wakeup(dev)) { - error = sysfs_merge_group(&client->dev.kobj, - &cyapa_power_wakeup_group); + error = sysfs_merge_group(&dev->kobj, + &cyapa_power_wakeup_group); if (error) { dev_err(dev, "failed to add power wakeup group: %d\n", error); @@ -1312,7 +1312,7 @@ static int cyapa_probe(struct i2c_client *client, return error; } - error = sysfs_create_group(&client->dev.kobj, &cyapa_sysfs_group); + error = sysfs_create_group(&dev->kobj, &cyapa_sysfs_group); if (error) { dev_err(dev, "failed to create sysfs entries: %d\n", error); return error; diff --git a/drivers/input/mouse/cyapa_gen3.c b/drivers/input/mouse/cyapa_gen3.c index f9600753eca5..1cbfa4a6e830 100644 --- a/drivers/input/mouse/cyapa_gen3.c +++ b/drivers/input/mouse/cyapa_gen3.c @@ -562,7 +562,7 @@ static int cyapa_gen3_bl_exit(struct cyapa *cyapa) * Wait for bootloader to exit, and operation mode to start. * Normally, this takes at least 50 ms. */ - usleep_range(50000, 100000); + msleep(50); /* * In addition, when a device boots for the first time after being * updated to new firmware, it must first calibrate its sensors, which @@ -789,7 +789,7 @@ static ssize_t cyapa_gen3_do_calibrate(struct device *dev, const char *buf, size_t count) { struct cyapa *cyapa = dev_get_drvdata(dev); - int tries; + unsigned long timeout; int ret; ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS); @@ -812,31 +812,28 @@ static ssize_t cyapa_gen3_do_calibrate(struct device *dev, goto out; } - tries = 20; /* max recalibration timeout 2s. */ + /* max recalibration timeout 2s. */ + timeout = jiffies + 2 * HZ; do { /* * For this recalibration, the max time will not exceed 2s. * The average time is approximately 500 - 700 ms, and we * will check the status every 100 - 200ms. */ - usleep_range(100000, 200000); - + msleep(100); ret = cyapa_read_byte(cyapa, CYAPA_CMD_DEV_STATUS); if (ret < 0) { - dev_err(dev, "Error reading dev status: %d\n", - ret); + dev_err(dev, "Error reading dev status: %d\n", ret); goto out; } - if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL) - break; - } while (--tries); + if ((ret & CYAPA_DEV_NORMAL) == CYAPA_DEV_NORMAL) { + dev_dbg(dev, "Calibration successful.\n"); + goto out; + } + } while (time_is_after_jiffies(timeout)); - if (tries == 0) { - dev_err(dev, "Failed to calibrate. Timeout.\n"); - ret = -ETIMEDOUT; - goto out; - } - dev_dbg(dev, "Calibration successful.\n"); + dev_err(dev, "Failed to calibrate. Timeout.\n"); + ret = -ETIMEDOUT; out: return ret < 0 ? ret : count; diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 28dcfc822bf6..21bad3e75fee 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -107,7 +107,7 @@ static int cypress_ps2_read_cmd_status(struct psmouse *psmouse, enum psmouse_state old_state; int pktsize; - ps2_begin_command(&psmouse->ps2dev); + ps2_begin_command(ps2dev); old_state = psmouse->state; psmouse->state = PSMOUSE_CMD_MODE; @@ -133,7 +133,7 @@ out: psmouse->state = old_state; psmouse->pktcnt = 0; - ps2_end_command(&psmouse->ps2dev); + ps2_end_command(ps2dev); return rc; } @@ -414,8 +414,6 @@ static int cypress_set_input_params(struct input_dev *input, __set_bit(BTN_RIGHT, input->keybit); __set_bit(BTN_MIDDLE, input->keybit); - input_set_drvdata(input, cytp); - return 0; } diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index fa598f7f4372..2c7d2872636c 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1041,8 +1041,7 @@ static int elan_probe(struct i2c_client *client, return -EIO; } - data = devm_kzalloc(&client->dev, sizeof(struct elan_tp_data), - GFP_KERNEL); + data = devm_kzalloc(dev, sizeof(struct elan_tp_data), GFP_KERNEL); if (!data) return -ENOMEM; @@ -1053,29 +1052,25 @@ static int elan_probe(struct i2c_client *client, init_completion(&data->fw_completion); mutex_init(&data->sysfs_mutex); - data->vcc = devm_regulator_get(&client->dev, "vcc"); + data->vcc = devm_regulator_get(dev, "vcc"); if (IS_ERR(data->vcc)) { error = PTR_ERR(data->vcc); if (error != -EPROBE_DEFER) - dev_err(&client->dev, - "Failed to get 'vcc' regulator: %d\n", + dev_err(dev, "Failed to get 'vcc' regulator: %d\n", error); return error; } error = regulator_enable(data->vcc); if (error) { - dev_err(&client->dev, - "Failed to enable regulator: %d\n", error); + dev_err(dev, "Failed to enable regulator: %d\n", error); return error; } - error = devm_add_action(&client->dev, - elan_disable_regulator, data); + error = devm_add_action(dev, elan_disable_regulator, data); if (error) { regulator_disable(data->vcc); - dev_err(&client->dev, - "Failed to add disable regulator action: %d\n", + dev_err(dev, "Failed to add disable regulator action: %d\n", error); return error; } @@ -1093,14 +1088,14 @@ static int elan_probe(struct i2c_client *client, if (error) return error; - dev_info(&client->dev, + dev_info(dev, "Elan Touchpad: Module ID: 0x%04x, Firmware: 0x%04x, Sample: 0x%04x, IAP: 0x%04x\n", data->product_id, data->fw_version, data->sm_version, data->iap_version); - dev_dbg(&client->dev, + dev_dbg(dev, "Elan Touchpad Extra Information:\n" " Max ABS X,Y: %d,%d\n" " Width X,Y: %d,%d\n" @@ -1118,38 +1113,33 @@ static int elan_probe(struct i2c_client *client, * Systems using device tree should set up interrupt via DTS, * the rest will use the default falling edge interrupts. */ - irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING; + irqflags = dev->of_node ? 0 : IRQF_TRIGGER_FALLING; - error = devm_request_threaded_irq(&client->dev, client->irq, - NULL, elan_isr, + error = devm_request_threaded_irq(dev, client->irq, NULL, elan_isr, irqflags | IRQF_ONESHOT, client->name, data); if (error) { - dev_err(&client->dev, "cannot register irq=%d\n", client->irq); + dev_err(dev, "cannot register irq=%d\n", client->irq); return error; } - error = sysfs_create_groups(&client->dev.kobj, elan_sysfs_groups); + error = sysfs_create_groups(&dev->kobj, elan_sysfs_groups); if (error) { - dev_err(&client->dev, "failed to create sysfs attributes: %d\n", - error); + dev_err(dev, "failed to create sysfs attributes: %d\n", error); return error; } - error = devm_add_action(&client->dev, - elan_remove_sysfs_groups, data); + error = devm_add_action(dev, elan_remove_sysfs_groups, data); if (error) { elan_remove_sysfs_groups(data); - dev_err(&client->dev, - "Failed to add sysfs cleanup action: %d\n", + dev_err(dev, "Failed to add sysfs cleanup action: %d\n", error); return error; } error = input_register_device(data->input); if (error) { - dev_err(&client->dev, "failed to register input device: %d\n", - error); + dev_err(dev, "failed to register input device: %d\n", error); return error; } @@ -1157,8 +1147,8 @@ static int elan_probe(struct i2c_client *client, * Systems using device tree should set up wakeup via DTS, * the rest will configure device as wakeup source by default. */ - if (!client->dev.of_node) - device_init_wakeup(&client->dev, true); + if (!dev->of_node) + device_init_wakeup(dev, true); return 0; } diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index db7d1d666ac1..efc8ec342351 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c @@ -1412,7 +1412,7 @@ int elantech_detect(struct psmouse *psmouse, bool set_properties) struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[3]; - ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); + ps2_command(ps2dev, NULL, PSMOUSE_CMD_RESET_DIS); if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_DISABLE) || ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSCALE11) || diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c index 62be888e83d0..015509e0b140 100644 --- a/drivers/input/mouse/hgpk.c +++ b/drivers/input/mouse/hgpk.c @@ -713,8 +713,7 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) * the upper bound. (in practice, it takes about 3 loops.) */ for (timeo = 20; timeo > 0; timeo--) { - if (!ps2_sendbyte(&psmouse->ps2dev, - PSMOUSE_CMD_DISABLE, 20)) + if (!ps2_sendbyte(ps2dev, PSMOUSE_CMD_DISABLE, 20)) break; msleep(25); } @@ -740,7 +739,7 @@ static int hgpk_toggle_powersave(struct psmouse *psmouse, int enable) psmouse_set_state(psmouse, PSMOUSE_IGNORE); /* probably won't see an ACK, the touchpad will be off */ - ps2_sendbyte(&psmouse->ps2dev, 0xec, 20); + ps2_sendbyte(ps2dev, 0xec, 20); } return 0; diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index 422da1cd9e76..ef9c97f5e3d7 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c @@ -402,7 +402,7 @@ int ps2pp_detect(struct psmouse *psmouse, bool set_properties) psmouse->set_resolution = ps2pp_set_resolution; psmouse->disconnect = ps2pp_disconnect; - error = device_create_file(&psmouse->ps2dev.serio->dev, + error = device_create_file(&ps2dev->serio->dev, &psmouse_attr_smartscroll.dattr); if (error) { psmouse_err(psmouse, diff --git a/drivers/input/mouse/maplemouse.c b/drivers/input/mouse/maplemouse.c index 0a60717b91c6..25f0ecb90126 100644 --- a/drivers/input/mouse/maplemouse.c +++ b/drivers/input/mouse/maplemouse.c @@ -87,7 +87,6 @@ static int probe_maple_mouse(struct device *dev) mse->dev = input_dev; mse->mdev = mdev; - input_set_drvdata(input_dev, mse); input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL); input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE); diff --git a/drivers/input/mouse/trackpoint.c b/drivers/input/mouse/trackpoint.c index 7331084973e1..922ea02edcc3 100644 --- a/drivers/input/mouse/trackpoint.c +++ b/drivers/input/mouse/trackpoint.c @@ -379,7 +379,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) if (!set_properties) return 0; - if (trackpoint_read(&psmouse->ps2dev, TP_EXT_BTN, &button_info)) { + if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) { psmouse_warn(psmouse, "failed to get extended button data\n"); button_info = 0; } @@ -402,7 +402,7 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties) trackpoint_defaults(psmouse->private); - error = trackpoint_power_on_reset(&psmouse->ps2dev); + error = trackpoint_power_on_reset(ps2dev); /* Write defaults to TP only if reset fails. */ if (error) diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 2e4ff5bac754..e420fd781d44 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -159,13 +159,12 @@ static int psif_open(struct serio *io) retval = clk_enable(psif->pclk); if (retval) - goto out; + return retval; psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); psif_writel(psif, IER, PSIF_BIT(RXRDY)); psif->open = true; -out: return retval; } @@ -210,16 +209,12 @@ static int __init psif_probe(struct platform_device *pdev) int ret; psif = kzalloc(sizeof(struct psif), GFP_KERNEL); - if (!psif) { - dev_dbg(&pdev->dev, "out of memory\n"); - ret = -ENOMEM; - goto out; - } + if (!psif) + return -ENOMEM; psif->pdev = pdev; io = kzalloc(sizeof(struct serio), GFP_KERNEL); if (!io) { - dev_dbg(&pdev->dev, "out of memory\n"); ret = -ENOMEM; goto out_free_psif; } @@ -297,7 +292,6 @@ out_free_io: kfree(io); out_free_psif: kfree(psif); -out: return ret; } diff --git a/drivers/input/serio/hyperv-keyboard.c b/drivers/input/serio/hyperv-keyboard.c index c948866edf87..25151d9214e0 100644 --- a/drivers/input/serio/hyperv-keyboard.c +++ b/drivers/input/serio/hyperv-keyboard.c @@ -402,7 +402,6 @@ static int hv_kbd_remove(struct hv_device *hv_dev) { struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev); - device_init_wakeup(&hv_dev->device, false); serio_unregister_port(kbd_dev->hv_serio); vmbus_close(hv_dev->channel); kfree(kbd_dev); diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h index a7618776705a..05afd16ea9c9 100644 --- a/drivers/input/serio/i8042-x86ia64io.h +++ b/drivers/input/serio/i8042-x86ia64io.h @@ -923,6 +923,10 @@ static struct pnp_driver i8042_pnp_kbd_driver = { .name = "i8042 kbd", .id_table = pnp_kbd_devids, .probe = i8042_pnp_kbd_probe, + .driver = { + .probe_type = PROBE_FORCE_SYNCHRONOUS, + .suppress_bind_attrs = true, + }, }; static struct pnp_device_id pnp_aux_devids[] = { @@ -945,6 +949,10 @@ static struct pnp_driver i8042_pnp_aux_driver = { .name = "i8042 aux", .id_table = pnp_aux_devids, .probe = i8042_pnp_aux_probe, + .driver = { + .probe_type = PROBE_FORCE_SYNCHRONOUS, + .suppress_bind_attrs = true, + }, }; static void i8042_pnp_exit(void) diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 62685a768913..c52da651269b 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c @@ -312,8 +312,10 @@ static int __i8042_command(unsigned char *param, int command) for (i = 0; i < ((command >> 12) & 0xf); i++) { error = i8042_wait_write(); - if (error) + if (error) { + dbg(" -- i8042 (wait write timeout)\n"); return error; + } dbg("%02x -> i8042 (parameter)\n", param[i]); i8042_write_data(param[i]); } @@ -321,7 +323,7 @@ static int __i8042_command(unsigned char *param, int command) for (i = 0; i < ((command >> 8) & 0xf); i++) { error = i8042_wait_read(); if (error) { - dbg(" -- i8042 (timeout)\n"); + dbg(" -- i8042 (wait read timeout)\n"); return error; } diff --git a/drivers/input/serio/xilinx_ps2.c b/drivers/input/serio/xilinx_ps2.c index 5223cbf94262..14c40892ed82 100644 --- a/drivers/input/serio/xilinx_ps2.c +++ b/drivers/input/serio/xilinx_ps2.c @@ -243,18 +243,17 @@ static int xps2_of_probe(struct platform_device *ofdev) unsigned int irq; int error; - dev_info(dev, "Device Tree Probing \'%s\'\n", - ofdev->dev.of_node->name); + dev_info(dev, "Device Tree Probing \'%s\'\n", dev->of_node->name); /* Get iospace for the device */ - error = of_address_to_resource(ofdev->dev.of_node, 0, &r_mem); + error = of_address_to_resource(dev->of_node, 0, &r_mem); if (error) { dev_err(dev, "invalid address\n"); return error; } /* Get IRQ for the device */ - irq = irq_of_parse_and_map(ofdev->dev.of_node, 0); + irq = irq_of_parse_and_map(dev->of_node, 0); if (!irq) { dev_err(dev, "no IRQ found\n"); return -ENODEV; diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c index 251ff2aa0633..7ed828a51f4c 100644 --- a/drivers/input/touchscreen/88pm860x-ts.c +++ b/drivers/input/touchscreen/88pm860x-ts.c @@ -240,8 +240,6 @@ static int pm860x_touch_probe(struct platform_device *pdev) if (!touch) return -ENOMEM; - platform_set_drvdata(pdev, touch); - touch->idev = devm_input_allocate_device(&pdev->dev); if (!touch->idev) { dev_err(&pdev->dev, "Failed to allocate input device!\n"); @@ -285,7 +283,6 @@ static int pm860x_touch_probe(struct platform_device *pdev) return ret; } - platform_set_drvdata(pdev, touch); return 0; } diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index efca0133e266..8650c94e29d0 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -546,18 +546,6 @@ config TOUCHSCREEN_INEXIO To compile this driver as a module, choose M here: the module will be called inexio. -config TOUCHSCREEN_INTEL_MID - tristate "Intel MID platform resistive touchscreen" - depends on INTEL_SCU_IPC - help - Say Y here if you have a Intel MID based touchscreen in - your system. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called intel_mid_touch. - config TOUCHSCREEN_MK712 tristate "ICS MicroClock MK712 touchscreen" help diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 81b86451782d..e41e3c7aa427 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -42,7 +42,6 @@ obj-$(CONFIG_TOUCHSCREEN_GOODIX) += goodix.o obj-$(CONFIG_TOUCHSCREEN_ILI210X) += ili210x.o obj-$(CONFIG_TOUCHSCREEN_IMX6UL_TSC) += imx6ul_tsc.o obj-$(CONFIG_TOUCHSCREEN_INEXIO) += inexio.o -obj-$(CONFIG_TOUCHSCREEN_INTEL_MID) += intel-mid-touch.o obj-$(CONFIG_TOUCHSCREEN_IPROC) += bcm_iproc_tsc.o obj-$(CONFIG_TOUCHSCREEN_LPC32XX) += lpc32xx_ts.o obj-$(CONFIG_TOUCHSCREEN_MAX11801) += max11801_ts.o diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 1ce3ecbe37f8..f5793e3d945f 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -1462,8 +1462,6 @@ static int ads7846_remove(struct spi_device *spi) { struct ads7846 *ts = spi_get_drvdata(spi); - device_init_wakeup(&spi->dev, false); - sysfs_remove_group(&spi->dev.kobj, &ads784x_attr_group); ads7846_disable(ts); diff --git a/drivers/input/touchscreen/ar1021_i2c.c b/drivers/input/touchscreen/ar1021_i2c.c index 71b5a634cf6d..6562b17117f7 100644 --- a/drivers/input/touchscreen/ar1021_i2c.c +++ b/drivers/input/touchscreen/ar1021_i2c.c @@ -127,7 +127,6 @@ static int ar1021_i2c_probe(struct i2c_client *client, return error; } - i2c_set_clientdata(client, ar1021); return 0; } diff --git a/drivers/input/touchscreen/atmel-wm97xx.c b/drivers/input/touchscreen/atmel-wm97xx.c index 7ec0421c0dd8..8cf0b2be2df4 100644 --- a/drivers/input/touchscreen/atmel-wm97xx.c +++ b/drivers/input/touchscreen/atmel-wm97xx.c @@ -339,10 +339,8 @@ static int __init atmel_wm97xx_probe(struct platform_device *pdev) int ret; atmel_wm97xx = kzalloc(sizeof(struct atmel_wm97xx), GFP_KERNEL); - if (!atmel_wm97xx) { - dev_dbg(&pdev->dev, "out of memory\n"); + if (!atmel_wm97xx) return -ENOMEM; - } atmel_wm97xx->wm = wm; atmel_wm97xx->regs = (void *)ATMEL_WM97XX_AC97C_IOMEM; diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index e5d185fe69b9..2302aef2b2d4 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -2509,7 +2509,7 @@ static void mxt_debug_init(struct mxt_data *data) dbg->t37_pages = MXT1386_COLUMNS * MXT1386_PAGES_PER_COLUMN; else dbg->t37_pages = DIV_ROUND_UP(data->xsize * - data->info.matrix_ysize * + info->matrix_ysize * sizeof(u16), sizeof(dbg->t37_buf->data)); diff --git a/drivers/input/touchscreen/bu21013_ts.c b/drivers/input/touchscreen/bu21013_ts.c index 931417eb4f5a..4fa5da8d5fa8 100644 --- a/drivers/input/touchscreen/bu21013_ts.c +++ b/drivers/input/touchscreen/bu21013_ts.c @@ -637,8 +637,6 @@ static int bu21013_remove(struct i2c_client *client) kfree(bu21013_data); - device_init_wakeup(&client->dev, false); - return 0; } diff --git a/drivers/input/touchscreen/colibri-vf50-ts.c b/drivers/input/touchscreen/colibri-vf50-ts.c index 69828d015d45..69c08acae264 100644 --- a/drivers/input/touchscreen/colibri-vf50-ts.c +++ b/drivers/input/touchscreen/colibri-vf50-ts.c @@ -311,8 +311,6 @@ static int vf50_ts_probe(struct platform_device *pdev) return -ENOMEM; } - platform_set_drvdata(pdev, touchdev); - input->name = DRIVER_NAME; input->id.bustype = BUS_HOST; input->dev.parent = dev; diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c index 28466e358fee..8cf8d8d5d4ef 100644 --- a/drivers/input/touchscreen/edt-ft5x06.c +++ b/drivers/input/touchscreen/edt-ft5x06.c @@ -67,7 +67,7 @@ #define EDT_SWITCH_MODE_RETRIES 10 #define EDT_SWITCH_MODE_DELAY 5 /* msec */ #define EDT_RAW_DATA_RETRIES 100 -#define EDT_RAW_DATA_DELAY 1 /* msec */ +#define EDT_RAW_DATA_DELAY 1000 /* usec */ enum edt_ver { M06, @@ -664,7 +664,7 @@ static ssize_t edt_ft5x06_debugfs_raw_data_read(struct file *file, } do { - msleep(EDT_RAW_DATA_DELAY); + usleep_range(EDT_RAW_DATA_DELAY, EDT_RAW_DATA_DELAY + 100); val = edt_ft5x06_register_read(tsdata, 0x08); if (val < 1) break; @@ -982,7 +982,6 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client, return error; } - input_set_drvdata(input, tsdata); i2c_set_clientdata(client, tsdata); irq_flags = irq_get_trigger_type(client->irq); diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 09be6ced7151..16023867b9da 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c @@ -173,12 +173,11 @@ static int eeti_ts_probe(struct i2c_client *client, priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) { dev_err(&client->dev, "failed to allocate driver data\n"); - goto err0; + return -ENOMEM; } mutex_init(&priv->mutex); input = input_allocate_device(); - if (!input) { dev_err(&client->dev, "Failed to allocate input device.\n"); goto err1; @@ -232,7 +231,6 @@ static int eeti_ts_probe(struct i2c_client *client, */ eeti_ts_stop(priv); - device_init_wakeup(&client->dev, 0); return 0; err3: @@ -243,7 +241,6 @@ err2: err1: input_free_device(input); kfree(priv); -err0: return err; } diff --git a/drivers/input/touchscreen/egalax_ts.c b/drivers/input/touchscreen/egalax_ts.c index 1afc08b08155..752ae9cf4514 100644 --- a/drivers/input/touchscreen/egalax_ts.c +++ b/drivers/input/touchscreen/egalax_ts.c @@ -214,8 +214,6 @@ static int egalax_ts_probe(struct i2c_client *client, ABS_MT_POSITION_Y, 0, EGALAX_MAX_Y, 0, 0); input_mt_init_slots(input_dev, MAX_SUPPORT_POINTS, 0); - input_set_drvdata(input_dev, ts); - error = devm_request_threaded_irq(&client->dev, client->irq, NULL, egalax_ts_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, @@ -229,7 +227,6 @@ static int egalax_ts_probe(struct i2c_client *client, if (error) return error; - i2c_set_clientdata(client, ts); return 0; } diff --git a/drivers/input/touchscreen/elants_i2c.c b/drivers/input/touchscreen/elants_i2c.c index 3e6003d32e56..872750eeca93 100644 --- a/drivers/input/touchscreen/elants_i2c.c +++ b/drivers/input/touchscreen/elants_i2c.c @@ -1260,8 +1260,6 @@ static int elants_i2c_probe(struct i2c_client *client, input_abs_set_res(ts->input, ABS_MT_POSITION_X, ts->x_res); input_abs_set_res(ts->input, ABS_MT_POSITION_Y, ts->y_res); - input_set_drvdata(ts->input, ts); - error = input_register_device(ts->input); if (error) { dev_err(&client->dev, diff --git a/drivers/input/touchscreen/fsl-imx25-tcq.c b/drivers/input/touchscreen/fsl-imx25-tcq.c index d50ee490c9cc..47fe1f184bbc 100644 --- a/drivers/input/touchscreen/fsl-imx25-tcq.c +++ b/drivers/input/touchscreen/fsl-imx25-tcq.c @@ -507,7 +507,7 @@ static int mx25_tcq_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct input_dev *idev; struct mx25_tcq_priv *priv; - struct mx25_tsadc *tsadc = dev_get_drvdata(pdev->dev.parent); + struct mx25_tsadc *tsadc = dev_get_drvdata(dev->parent); struct resource *res; void __iomem *mem; int error; diff --git a/drivers/input/touchscreen/ili210x.c b/drivers/input/touchscreen/ili210x.c index fe4848bd1f4c..6f76eeedf465 100644 --- a/drivers/input/touchscreen/ili210x.c +++ b/drivers/input/touchscreen/ili210x.c @@ -256,7 +256,6 @@ static int ili210x_i2c_probe(struct i2c_client *client, input_set_abs_params(input, ABS_MT_POSITION_X, 0, xmax, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, ymax, 0, 0); - input_set_drvdata(input, priv); i2c_set_clientdata(client, priv); error = request_irq(client->irq, ili210x_irq, pdata->irq_flags, @@ -280,7 +279,7 @@ static int ili210x_i2c_probe(struct i2c_client *client, goto err_remove_sysfs; } - device_init_wakeup(&client->dev, 1); + device_init_wakeup(dev, 1); dev_dbg(dev, "ILI210x initialized (IRQ: %d), firmware version %d.%d.%d", diff --git a/drivers/input/touchscreen/intel-mid-touch.c b/drivers/input/touchscreen/intel-mid-touch.c deleted file mode 100644 index b4f0725a1c3d..000000000000 --- a/drivers/input/touchscreen/intel-mid-touch.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Intel MID Resistive Touch Screen Driver - * - * Copyright (C) 2008 Intel Corp - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * Questions/Comments/Bug fixes to Sreedhara ([email protected]) - * Ramesh Agarwal ([email protected]) - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * TODO: - * review conversion of r/m/w sequences - */ - -#include <linux/module.h> -#include <linux/input.h> -#include <linux/interrupt.h> -#include <linux/err.h> -#include <linux/param.h> -#include <linux/slab.h> -#include <linux/platform_device.h> -#include <linux/irq.h> -#include <linux/delay.h> -#include <asm/intel_scu_ipc.h> -#include <linux/device.h> - -/* PMIC Interrupt registers */ -#define PMIC_REG_ID1 0x00 /* PMIC ID1 register */ - -/* PMIC Interrupt registers */ -#define PMIC_REG_INT 0x04 /* PMIC interrupt register */ -#define PMIC_REG_MINT 0x05 /* PMIC interrupt mask register */ - -/* ADC Interrupt registers */ -#define PMIC_REG_ADCINT 0x5F /* ADC interrupt register */ -#define PMIC_REG_MADCINT 0x60 /* ADC interrupt mask register */ - -/* ADC Control registers */ -#define PMIC_REG_ADCCNTL1 0x61 /* ADC control register */ - -/* ADC Channel Selection registers */ -#define PMICADDR0 0xA4 -#define END_OF_CHANNEL 0x1F - -/* ADC Result register */ -#define PMIC_REG_ADCSNS0H 0x64 - -/* ADC channels for touch screen */ -#define MRST_TS_CHAN10 0xA /* Touch screen X+ connection */ -#define MRST_TS_CHAN11 0xB /* Touch screen X- connection */ -#define MRST_TS_CHAN12 0xC /* Touch screen Y+ connection */ -#define MRST_TS_CHAN13 0xD /* Touch screen Y- connection */ - -/* Touch screen channel BIAS constants */ -#define MRST_XBIAS 0x20 -#define MRST_YBIAS 0x40 -#define MRST_ZBIAS 0x80 - -/* Touch screen coordinates */ -#define MRST_X_MIN 10 -#define MRST_X_MAX 1024 -#define MRST_X_FUZZ 5 -#define MRST_Y_MIN 10 -#define MRST_Y_MAX 1024 -#define MRST_Y_FUZZ 5 -#define MRST_PRESSURE_MIN 0 -#define MRST_PRESSURE_NOMINAL 50 -#define MRST_PRESSURE_MAX 100 - -#define WAIT_ADC_COMPLETION 10 /* msec */ - -/* PMIC ADC round robin delays */ -#define ADC_LOOP_DELAY0 0x0 /* Continuous loop */ -#define ADC_LOOP_DELAY1 0x1 /* 4.5 ms approximate */ - -/* PMIC Vendor Identifiers */ -#define PMIC_VENDOR_FS 0 /* PMIC vendor FreeScale */ -#define PMIC_VENDOR_MAXIM 1 /* PMIC vendor MAXIM */ -#define PMIC_VENDOR_NEC 2 /* PMIC vendor NEC */ -#define MRSTOUCH_MAX_CHANNELS 32 /* Maximum ADC channels */ - -/* Touch screen device structure */ -struct mrstouch_dev { - struct device *dev; /* device associated with touch screen */ - struct input_dev *input; - char phys[32]; - u16 asr; /* Address selection register */ - int irq; - unsigned int vendor; /* PMIC vendor */ - unsigned int rev; /* PMIC revision */ - - int (*read_prepare)(struct mrstouch_dev *tsdev); - int (*read)(struct mrstouch_dev *tsdev, u16 *x, u16 *y, u16 *z); - int (*read_finish)(struct mrstouch_dev *tsdev); -}; - - -/*************************** NEC and Maxim Interface ************************/ - -static int mrstouch_nec_adc_read_prepare(struct mrstouch_dev *tsdev) -{ - return intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0, 0x20); -} - -/* - * Enables PENDET interrupt. - */ -static int mrstouch_nec_adc_read_finish(struct mrstouch_dev *tsdev) -{ - int err; - - err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x20, 0x20); - if (!err) - err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, 0, 0x05); - - return err; -} - -/* - * Reads PMIC ADC touch screen result - * Reads ADC storage registers for higher 7 and lower 3 bits and - * converts the two readings into a single value and turns off gain bit - */ -static int mrstouch_ts_chan_read(u16 offset, u16 chan, u16 *vp, u16 *vm) -{ - int err; - u16 result; - u32 res; - - result = PMIC_REG_ADCSNS0H + offset; - - if (chan == MRST_TS_CHAN12) - result += 4; - - err = intel_scu_ipc_ioread32(result, &res); - if (err) - return err; - - /* Mash the bits up */ - - *vp = (res & 0xFF) << 3; /* Highest 7 bits */ - *vp |= (res >> 8) & 0x07; /* Lower 3 bits */ - *vp &= 0x3FF; - - res >>= 16; - - *vm = (res & 0xFF) << 3; /* Highest 7 bits */ - *vm |= (res >> 8) & 0x07; /* Lower 3 bits */ - *vm &= 0x3FF; - - return 0; -} - -/* - * Enables X, Y and Z bias values - * Enables YPYM for X channels and XPXM for Y channels - */ -static int mrstouch_ts_bias_set(uint offset, uint bias) -{ - int count; - u16 chan, start; - u16 reg[4]; - u8 data[4]; - - chan = PMICADDR0 + offset; - start = MRST_TS_CHAN10; - - for (count = 0; count <= 3; count++) { - reg[count] = chan++; - data[count] = bias | (start + count); - } - - return intel_scu_ipc_writev(reg, data, 4); -} - -/* To read touch screen channel values */ -static int mrstouch_nec_adc_read(struct mrstouch_dev *tsdev, - u16 *x, u16 *y, u16 *z) -{ - int err; - u16 xm, ym, zm; - - /* configure Y bias for X channels */ - err = mrstouch_ts_bias_set(tsdev->asr, MRST_YBIAS); - if (err) - goto ipc_error; - - msleep(WAIT_ADC_COMPLETION); - - /* read x+ and x- channels */ - err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, x, &xm); - if (err) - goto ipc_error; - - /* configure x bias for y channels */ - err = mrstouch_ts_bias_set(tsdev->asr, MRST_XBIAS); - if (err) - goto ipc_error; - - msleep(WAIT_ADC_COMPLETION); - - /* read y+ and y- channels */ - err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN12, y, &ym); - if (err) - goto ipc_error; - - /* configure z bias for x and y channels */ - err = mrstouch_ts_bias_set(tsdev->asr, MRST_ZBIAS); - if (err) - goto ipc_error; - - msleep(WAIT_ADC_COMPLETION); - - /* read z+ and z- channels */ - err = mrstouch_ts_chan_read(tsdev->asr, MRST_TS_CHAN10, z, &zm); - if (err) - goto ipc_error; - - return 0; - -ipc_error: - dev_err(tsdev->dev, "ipc error during adc read\n"); - return err; -} - - -/*************************** Freescale Interface ************************/ - -static int mrstouch_fs_adc_read_prepare(struct mrstouch_dev *tsdev) -{ - int err, count; - u16 chan; - u16 reg[5]; - u8 data[5]; - - /* Stop the ADC */ - err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x00, 0x02); - if (err) - goto ipc_error; - - chan = PMICADDR0 + tsdev->asr; - - /* Set X BIAS */ - for (count = 0; count <= 3; count++) { - reg[count] = chan++; - data[count] = 0x2A; - } - reg[count] = chan++; /* Dummy */ - data[count] = 0; - - err = intel_scu_ipc_writev(reg, data, 5); - if (err) - goto ipc_error; - - msleep(WAIT_ADC_COMPLETION); - - /* Set Y BIAS */ - for (count = 0; count <= 3; count++) { - reg[count] = chan++; - data[count] = 0x4A; - } - reg[count] = chan++; /* Dummy */ - data[count] = 0; - - err = intel_scu_ipc_writev(reg, data, 5); - if (err) - goto ipc_error; - - msleep(WAIT_ADC_COMPLETION); - - /* Set Z BIAS */ - err = intel_scu_ipc_iowrite32(chan + 2, 0x8A8A8A8A); - if (err) - goto ipc_error; - - msleep(WAIT_ADC_COMPLETION); - - return 0; - -ipc_error: - dev_err(tsdev->dev, "ipc error during %s\n", __func__); - return err; -} - -static int mrstouch_fs_adc_read(struct mrstouch_dev *tsdev, - u16 *x, u16 *y, u16 *z) -{ - int err; - u16 result; - u16 reg[4]; - u8 data[4]; - - result = PMIC_REG_ADCSNS0H + tsdev->asr; - - reg[0] = result + 4; - reg[1] = result + 5; - reg[2] = result + 16; - reg[3] = result + 17; - - err = intel_scu_ipc_readv(reg, data, 4); - if (err) - goto ipc_error; - - *x = data[0] << 3; /* Higher 7 bits */ - *x |= data[1] & 0x7; /* Lower 3 bits */ - *x &= 0x3FF; - - *y = data[2] << 3; /* Higher 7 bits */ - *y |= data[3] & 0x7; /* Lower 3 bits */ - *y &= 0x3FF; - - /* Read Z value */ - reg[0] = result + 28; - reg[1] = result + 29; - - err = intel_scu_ipc_readv(reg, data, 4); - if (err) - goto ipc_error; - - *z = data[0] << 3; /* Higher 7 bits */ - *z |= data[1] & 0x7; /* Lower 3 bits */ - *z &= 0x3FF; - - return 0; - -ipc_error: - dev_err(tsdev->dev, "ipc error during %s\n", __func__); - return err; -} - -static int mrstouch_fs_adc_read_finish(struct mrstouch_dev *tsdev) -{ - int err, count; - u16 chan; - u16 reg[5]; - u8 data[5]; - - /* Clear all TS channels */ - chan = PMICADDR0 + tsdev->asr; - for (count = 0; count <= 4; count++) { - reg[count] = chan++; - data[count] = 0; - } - err = intel_scu_ipc_writev(reg, data, 5); - if (err) - goto ipc_error; - - for (count = 0; count <= 4; count++) { - reg[count] = chan++; - data[count] = 0; - } - err = intel_scu_ipc_writev(reg, data, 5); - if (err) - goto ipc_error; - - err = intel_scu_ipc_iowrite32(chan + 2, 0x00000000); - if (err) - goto ipc_error; - - /* Start ADC */ - err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, 0x02, 0x02); - if (err) - goto ipc_error; - - return 0; - -ipc_error: - dev_err(tsdev->dev, "ipc error during %s\n", __func__); - return err; -} - -static void mrstouch_report_event(struct input_dev *input, - unsigned int x, unsigned int y, unsigned int z) -{ - if (z > MRST_PRESSURE_NOMINAL) { - /* Pen touched, report button touch and coordinates */ - input_report_key(input, BTN_TOUCH, 1); - input_report_abs(input, ABS_X, x); - input_report_abs(input, ABS_Y, y); - } else { - input_report_key(input, BTN_TOUCH, 0); - } - - input_report_abs(input, ABS_PRESSURE, z); - input_sync(input); -} - -/* PENDET interrupt handler */ -static irqreturn_t mrstouch_pendet_irq(int irq, void *dev_id) -{ - struct mrstouch_dev *tsdev = dev_id; - u16 x, y, z; - - /* - * Should we lower thread priority? Probably not, since we are - * not spinning but sleeping... - */ - - if (tsdev->read_prepare(tsdev)) - goto out; - - do { - if (tsdev->read(tsdev, &x, &y, &z)) - break; - - mrstouch_report_event(tsdev->input, x, y, z); - } while (z > MRST_PRESSURE_NOMINAL); - - tsdev->read_finish(tsdev); - -out: - return IRQ_HANDLED; -} - -/* Utility to read PMIC ID */ -static int mrstouch_read_pmic_id(uint *vendor, uint *rev) -{ - int err; - u8 r; - - err = intel_scu_ipc_ioread8(PMIC_REG_ID1, &r); - if (err) - return err; - - *vendor = r & 0x7; - *rev = (r >> 3) & 0x7; - - return 0; -} - -/* - * Parse ADC channels to find end of the channel configured by other ADC user - * NEC and MAXIM requires 4 channels and FreeScale needs 18 channels - */ -static int mrstouch_chan_parse(struct mrstouch_dev *tsdev) -{ - int found = 0; - int err, i; - u8 r8; - - for (i = 0; i < MRSTOUCH_MAX_CHANNELS; i++) { - err = intel_scu_ipc_ioread8(PMICADDR0 + i, &r8); - if (err) - return err; - - if (r8 == END_OF_CHANNEL) { - found = i; - break; - } - } - - if (tsdev->vendor == PMIC_VENDOR_FS) { - if (found > MRSTOUCH_MAX_CHANNELS - 18) - return -ENOSPC; - } else { - if (found > MRSTOUCH_MAX_CHANNELS - 4) - return -ENOSPC; - } - - return found; -} - - -/* - * Writes touch screen channels to ADC address selection registers - */ -static int mrstouch_ts_chan_set(uint offset) -{ - u16 chan; - - int ret, count; - - chan = PMICADDR0 + offset; - for (count = 0; count <= 3; count++) { - ret = intel_scu_ipc_iowrite8(chan++, MRST_TS_CHAN10 + count); - if (ret) - return ret; - } - return intel_scu_ipc_iowrite8(chan++, END_OF_CHANNEL); -} - -/* Initialize ADC */ -static int mrstouch_adc_init(struct mrstouch_dev *tsdev) -{ - int err, start; - u8 ra, rm; - - err = mrstouch_read_pmic_id(&tsdev->vendor, &tsdev->rev); - if (err) { - dev_err(tsdev->dev, "Unable to read PMIC id\n"); - return err; - } - - switch (tsdev->vendor) { - case PMIC_VENDOR_NEC: - case PMIC_VENDOR_MAXIM: - tsdev->read_prepare = mrstouch_nec_adc_read_prepare; - tsdev->read = mrstouch_nec_adc_read; - tsdev->read_finish = mrstouch_nec_adc_read_finish; - break; - - case PMIC_VENDOR_FS: - tsdev->read_prepare = mrstouch_fs_adc_read_prepare; - tsdev->read = mrstouch_fs_adc_read; - tsdev->read_finish = mrstouch_fs_adc_read_finish; - break; - - default: - dev_err(tsdev->dev, - "Unsupported touchscreen: %d\n", tsdev->vendor); - return -ENXIO; - } - - start = mrstouch_chan_parse(tsdev); - if (start < 0) { - dev_err(tsdev->dev, "Unable to parse channels\n"); - return start; - } - - tsdev->asr = start; - - /* - * ADC power on, start, enable PENDET and set loop delay - * ADC loop delay is set to 4.5 ms approximately - * Loop delay more than this results in jitter in adc readings - * Setting loop delay to 0 (continuous loop) in MAXIM stops PENDET - * interrupt generation sometimes. - */ - - if (tsdev->vendor == PMIC_VENDOR_FS) { - ra = 0xE0 | ADC_LOOP_DELAY0; - rm = 0x5; - } else { - /* NEC and MAXIm not consistent with loop delay 0 */ - ra = 0xE0 | ADC_LOOP_DELAY1; - rm = 0x0; - - /* configure touch screen channels */ - err = mrstouch_ts_chan_set(tsdev->asr); - if (err) - return err; - } - - err = intel_scu_ipc_update_register(PMIC_REG_ADCCNTL1, ra, 0xE7); - if (err) - return err; - - err = intel_scu_ipc_update_register(PMIC_REG_MADCINT, rm, 0x03); - if (err) - return err; - - return 0; -} - - -/* Probe function for touch screen driver */ -static int mrstouch_probe(struct platform_device *pdev) -{ - struct mrstouch_dev *tsdev; - struct input_dev *input; - int err; - int irq; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) { - dev_err(&pdev->dev, "no interrupt assigned\n"); - return -EINVAL; - } - - tsdev = devm_kzalloc(&pdev->dev, sizeof(struct mrstouch_dev), - GFP_KERNEL); - if (!tsdev) { - dev_err(&pdev->dev, "unable to allocate memory\n"); - return -ENOMEM; - } - - input = devm_input_allocate_device(&pdev->dev); - if (!input) { - dev_err(&pdev->dev, "unable to allocate input device\n"); - return -ENOMEM; - } - - tsdev->dev = &pdev->dev; - tsdev->input = input; - tsdev->irq = irq; - - snprintf(tsdev->phys, sizeof(tsdev->phys), - "%s/input0", dev_name(tsdev->dev)); - - err = mrstouch_adc_init(tsdev); - if (err) { - dev_err(&pdev->dev, "ADC initialization failed\n"); - return err; - } - - input->name = "mrst_touchscreen"; - input->phys = tsdev->phys; - input->dev.parent = tsdev->dev; - - input->id.vendor = tsdev->vendor; - input->id.version = tsdev->rev; - - input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); - input->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); - - input_set_abs_params(tsdev->input, ABS_X, - MRST_X_MIN, MRST_X_MAX, MRST_X_FUZZ, 0); - input_set_abs_params(tsdev->input, ABS_Y, - MRST_Y_MIN, MRST_Y_MAX, MRST_Y_FUZZ, 0); - input_set_abs_params(tsdev->input, ABS_PRESSURE, - MRST_PRESSURE_MIN, MRST_PRESSURE_MAX, 0, 0); - - err = devm_request_threaded_irq(&pdev->dev, tsdev->irq, NULL, - mrstouch_pendet_irq, IRQF_ONESHOT, - "mrstouch", tsdev); - if (err) { - dev_err(tsdev->dev, "unable to allocate irq\n"); - return err; - } - - err = input_register_device(tsdev->input); - if (err) { - dev_err(tsdev->dev, "unable to register input device\n"); - return err; - } - - return 0; -} - -static struct platform_driver mrstouch_driver = { - .driver = { - .name = "pmic_touch", - }, - .probe = mrstouch_probe, -}; -module_platform_driver(mrstouch_driver); - -MODULE_AUTHOR("Sreedhara Murthy. D.S, [email protected]"); -MODULE_DESCRIPTION("Intel Moorestown Resistive Touch Screen Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/lpc32xx_ts.c b/drivers/input/touchscreen/lpc32xx_ts.c index 7fbb3b0c8571..e0baa7de4102 100644 --- a/drivers/input/touchscreen/lpc32xx_ts.c +++ b/drivers/input/touchscreen/lpc32xx_ts.c @@ -313,7 +313,6 @@ static int lpc32xx_ts_remove(struct platform_device *pdev) struct lpc32xx_tsc *tsc = platform_get_drvdata(pdev); struct resource *res; - device_init_wakeup(&pdev->dev, 0); free_irq(tsc->irq, tsc); input_unregister_device(tsc->dev); diff --git a/drivers/input/touchscreen/max11801_ts.c b/drivers/input/touchscreen/max11801_ts.c index 82079cde849c..a595ae5284e3 100644 --- a/drivers/input/touchscreen/max11801_ts.c +++ b/drivers/input/touchscreen/max11801_ts.c @@ -199,7 +199,6 @@ static int max11801_ts_probe(struct i2c_client *client, __set_bit(BTN_TOUCH, input_dev->keybit); input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0); - input_set_drvdata(input_dev, data); max11801_ts_phy_init(data); @@ -216,7 +215,6 @@ static int max11801_ts_probe(struct i2c_client *client, if (error) return error; - i2c_set_clientdata(client, data); return 0; } diff --git a/drivers/input/touchscreen/mcs5000_ts.c b/drivers/input/touchscreen/mcs5000_ts.c index 8b47e1fecb25..90fc07dc98a6 100644 --- a/drivers/input/touchscreen/mcs5000_ts.c +++ b/drivers/input/touchscreen/mcs5000_ts.c @@ -221,7 +221,6 @@ static int mcs5000_ts_probe(struct i2c_client *client, input_set_abs_params(input_dev, ABS_X, 0, MCS5000_MAX_XC, 0, 0); input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); - input_set_drvdata(input_dev, data); data->input_dev = input_dev; if (pdata->cfg_pin) diff --git a/drivers/input/touchscreen/pixcir_i2c_ts.c b/drivers/input/touchscreen/pixcir_i2c_ts.c index 3bb0637d832e..37ff672c7802 100644 --- a/drivers/input/touchscreen/pixcir_i2c_ts.c +++ b/drivers/input/touchscreen/pixcir_i2c_ts.c @@ -461,7 +461,7 @@ static int pixcir_i2c_ts_probe(struct i2c_client *client, if (error) return error; } else { - dev_err(&client->dev, "platform data not defined\n"); + dev_err(dev, "platform data not defined\n"); return -EINVAL; } @@ -483,7 +483,7 @@ 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 = &client->dev; + input->dev.parent = dev; if (pdata) { input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index 2658afa016c9..1252e49ccfa1 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -1087,8 +1087,6 @@ static int raydium_i2c_probe(struct i2c_client *client, ts->input->name = "Raydium Touchscreen"; ts->input->id.bustype = BUS_I2C; - input_set_drvdata(ts->input, ts); - input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, le16_to_cpu(ts->info.x_max), 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, diff --git a/drivers/input/touchscreen/rohm_bu21023.c b/drivers/input/touchscreen/rohm_bu21023.c index 611156a2ef80..eeaf6ff03597 100644 --- a/drivers/input/touchscreen/rohm_bu21023.c +++ b/drivers/input/touchscreen/rohm_bu21023.c @@ -1189,8 +1189,7 @@ static int rohm_bu21023_i2c_probe(struct i2c_client *client, error = devm_add_action(dev, rohm_ts_remove_sysfs_group, dev); if (error) { rohm_ts_remove_sysfs_group(dev); - dev_err(&client->dev, - "Failed to add sysfs cleanup action: %d\n", + dev_err(dev, "Failed to add sysfs cleanup action: %d\n", error); return error; } diff --git a/drivers/input/touchscreen/s3c2410_ts.c b/drivers/input/touchscreen/s3c2410_ts.c index a4a103e1d11b..41d58e88cc8a 100644 --- a/drivers/input/touchscreen/s3c2410_ts.c +++ b/drivers/input/touchscreen/s3c2410_ts.c @@ -250,7 +250,7 @@ static int s3c2410ts_probe(struct platform_device *pdev) ts.dev = dev; - info = dev_get_platdata(&pdev->dev); + info = dev_get_platdata(dev); if (!info) { dev_err(dev, "no platform data, cannot attach\n"); return -EINVAL; diff --git a/drivers/input/touchscreen/sis_i2c.c b/drivers/input/touchscreen/sis_i2c.c index 8d93f8c9a403..67c2563031d6 100644 --- a/drivers/input/touchscreen/sis_i2c.c +++ b/drivers/input/touchscreen/sis_i2c.c @@ -316,7 +316,6 @@ static int sis_ts_probe(struct i2c_client *client, return -ENOMEM; ts->client = client; - i2c_set_clientdata(client, ts); ts->attn_gpio = devm_gpiod_get_optional(&client->dev, "attn", GPIOD_IN); diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index e943678ce54c..be5615c6bf8f 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -237,7 +237,6 @@ static int st1232_ts_remove(struct i2c_client *client) { struct st1232_ts_data *ts = i2c_get_clientdata(client); - device_init_wakeup(&client->dev, 0); st1232_ts_power(ts, false); return 0; diff --git a/drivers/input/touchscreen/sx8654.c b/drivers/input/touchscreen/sx8654.c index 642f4a53de50..ed29db3ec731 100644 --- a/drivers/input/touchscreen/sx8654.c +++ b/drivers/input/touchscreen/sx8654.c @@ -253,7 +253,6 @@ static int sx8654_probe(struct i2c_client *client, if (error) return error; - i2c_set_clientdata(client, sx8654); return 0; } diff --git a/include/linux/i2c/mpr121_touchkey.h b/include/linux/i2c/mpr121_touchkey.h deleted file mode 100644 index f0bcc38bbb97..000000000000 --- a/include/linux/i2c/mpr121_touchkey.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Header file for Freescale MPR121 Capacitive Touch Sensor */ - -#ifndef _MPR121_TOUCHKEY_H -#define _MPR121_TOUCHKEY_H - -/** - * struct mpr121_platform_data - platform data for mpr121 sensor - * @keymap: pointer to array of KEY_* values representing keymap - * @keymap_size: size of the keymap - * @wakeup: configure the button as a wake-up source - * @vdd_uv: VDD voltage in uV - */ -struct mpr121_platform_data { - const unsigned short *keymap; - unsigned int keymap_size; - bool wakeup; - int vdd_uv; -}; - -#endif /* _MPR121_TOUCHKEY_H */ |