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

Pull input updates from Dmitry:

 - a new driver for Zeitech touchscreen controller

 - a new driver for Samsung "touchkeys"

 - touchscreen driver for Moorestown platform has been removed because
   platform support is gone

 - MPU3050 accelerometer driver was removed in favor of IIO driver

 - miscellaneous driver cleanup and fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (88 commits)
  Input: zet6223 - export OF device ID as module aliases
  Input: tsc2004/5 - switch to using generic device properties
  Input: tsc2004/5 - fix regulator handling
  Input: tsc2005 - add OF device table
  Input: add driver for Zeitec ZET6223
  Input: joydev - do not report stale values on first open
  Input: synaptics-rmi4 - forward upper mechanical buttons to PS/2 guest
  Input: synaptics-rmi4 - clean up F30 implementation
  Input: synaptics - use SERIO_OOB_DATA to handle trackstick buttons
  Input: psmouse - add a custom serio protocol to send extra information
  Input: synaptics-rmi4 - fix error return code in rmi_probe_interrupts()
  Input: xpad - restore LED state after device resume
  Input: synaptics-rmi4 - add rmi_find_function()
  Input: xpad - fix stuck mode button on Xbox One S pad
  Input: joydev - use clamp() macro
  Input: refuse to register absolute devices without absinfo
  Input: synaptics-rmi4 - add sysfs interfaces for hardware IDs
  Input: synaptics-rmi4 - add sysfs attribute update_fw_status
  Input: mousedev - stop offering PS/2 to userspace by default
  Input: tca8418 - switch to using generic device properties
  ...
This commit is contained in:
Linus Torvalds 2017-02-23 08:39:40 -08:00
Родитель 4cc4b9323f 6e11617fcf
Коммит d5dee39b27
132 изменённых файлов: 1848 добавлений и 2201 удалений

Просмотреть файл

@ -0,0 +1,27 @@
Samsung tm2-touchkey
Required properties:
- compatible: must be "cypress,tm2-touchkey"
- reg: I2C address of the chip.
- interrupt-parent: a phandle for the interrupt controller (see interrupt
binding[0]).
- interrupts: interrupt to which the chip is connected (see interrupt
binding[0]).
- vcc-supply : internal regulator output. 1.8V
- vdd-supply : power supply for IC 3.3V
[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
Example:
&i2c0 {
/* ... */
touchkey@20 {
compatible = "cypress,tm2-touchkey";
reg = <0x20>;
interrupt-parent = <&gpa3>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
vcc-supply=<&ldo32_reg>;
vdd-supply=<&ldo33_reg>;
};
};

Просмотреть файл

@ -0,0 +1,30 @@
* Freescale MPR121 Controllor
Required Properties:
- compatible: Should be "fsl,mpr121-touchkey"
- reg: The I2C slave address of the device.
- interrupts: The interrupt number to the cpu.
- vdd-supply: Phandle to the Vdd power supply.
- linux,keycodes: Specifies an array of numeric keycode values to
be used for reporting button presses. The array can
contain up to 12 entries.
Optional Properties:
- wakeup-source: Use any event on keypad as wakeup event.
- autorepeat: Enable autorepeat feature.
Example:
#include "dt-bindings/input/input.h"
touchkey: mpr121@5a {
compatible = "fsl,mpr121-touchkey";
reg = <0x5a>;
interrupt-parent = <&gpio1>;
interrupts = <28 2>;
autorepeat;
vdd-supply = <&ldo4_reg>;
linux,keycodes = <KEY_0>, <KEY_1>, <KEY_2>, <KEY_3>,
<KEY_4> <KEY_5>, <KEY_6>, <KEY_7>,
<KEY_8>, <KEY_9>, <KEY_A>, <KEY_B>;
};

Просмотреть файл

@ -5,3 +5,19 @@ Registers a PWM device as beeper.
Required properties:
- compatible: should be "pwm-beeper"
- pwms: phandle to the physical PWM device
Optional properties:
- amp-supply: phandle to a regulator that acts as an amplifier for the beeper
Example:
beeper_amp: amplifier {
compatible = "fixed-regulator";
gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>;
};
beeper {
compatible = "pwm-beeper";
pwms = <&pwm0>;
amp-supply = <&beeper_amp>;
};

Просмотреть файл

@ -0,0 +1,32 @@
Zeitec ZET6223 I2C touchscreen controller
Required properties:
- compatible : "zeitec,zet6223"
- reg : I2C slave address of the chip (0x76)
- interrupt-parent : a phandle pointing to the interrupt controller
serving the interrupt for this chip
- interrupts : interrupt specification for the zet6223 interrupt
Optional properties:
- vio-supply : Specification for VIO supply (1.8V or 3.3V,
depending on system interface needs).
- vcc-supply : Specification for 3.3V VCC supply.
- touchscreen-size-x : See touchscreen.txt
- touchscreen-size-y : See touchscreen.txt
- touchscreen-inverted-x : See touchscreen.txt
- touchscreen-inverted-y : See touchscreen.txt
- touchscreen-swapped-x-y : See touchscreen.txt
Example:
i2c@00000000 {
zet6223: touchscreen@76 {
compatible = "zeitec,zet6223";
reg = <0x76>;
interrupt-parent = <&pio>;
interrupts = <6 11 IRQ_TYPE_EDGE_FALLING>
};
};

Просмотреть файл

@ -334,6 +334,7 @@ xes Extreme Engineering Solutions (X-ES)
xillybus Xillybus Ltd.
xlnx Xilinx
zarlink Zarlink Semiconductor
zeitec ZEITEC Semiconductor Co., LTD.
zii Zodiac Inflight Innovations
zte ZTE Corp.
zyxel ZyXEL Communications Corp.

Просмотреть файл

@ -94,7 +94,6 @@ comment "Userland interfaces"
config INPUT_MOUSEDEV
tristate "Mouse interface"
default y
help
Say Y here if you want your mouse to be accessible as char devices
13:32+ - /dev/input/mouseX and 13:63 - /dev/input/mice as an
@ -109,7 +108,6 @@ config INPUT_MOUSEDEV
config INPUT_MOUSEDEV_PSAUX
bool "Provide legacy /dev/psaux device"
default y
depends on INPUT_MOUSEDEV
help
Say Y here if you want your mouse also be accessible as char device
@ -118,7 +116,6 @@ config INPUT_MOUSEDEV_PSAUX
If unsure, say Y.
config INPUT_MOUSEDEV_SCREEN_X
int "Horizontal screen resolution"
depends on INPUT_MOUSEDEV

Просмотреть файл

@ -1749,7 +1749,7 @@ static const struct dev_pm_ops input_dev_pm_ops = {
};
#endif /* CONFIG_PM */
static struct device_type input_dev_type = {
static const struct device_type input_dev_type = {
.groups = input_dev_attr_groups,
.release = input_dev_release,
.uevent = input_dev_uevent,
@ -2091,6 +2091,12 @@ int input_register_device(struct input_dev *dev)
const char *path;
int error;
if (test_bit(EV_ABS, dev->evbit) && !dev->absinfo) {
dev_err(&dev->dev,
"Absolute device without dev->absinfo, refusing to register\n");
return -EINVAL;
}
if (dev->devres_managed) {
devres = devres_alloc(devm_input_device_unregister,
sizeof(struct input_devres), GFP_KERNEL);

Просмотреть файл

@ -87,7 +87,7 @@ static int joydev_correct(int value, struct js_corr *corr)
return 0;
}
return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
return clamp(value, -32767, 32767);
}
static void joydev_pass_event(struct joydev_client *client,
@ -187,6 +187,17 @@ static void joydev_detach_client(struct joydev *joydev,
synchronize_rcu();
}
static void joydev_refresh_state(struct joydev *joydev)
{
struct input_dev *dev = joydev->handle.dev;
int i, val;
for (i = 0; i < joydev->nabs; i++) {
val = input_abs_get_val(dev, joydev->abspam[i]);
joydev->abs[i] = joydev_correct(val, &joydev->corr[i]);
}
}
static int joydev_open_device(struct joydev *joydev)
{
int retval;
@ -201,6 +212,8 @@ static int joydev_open_device(struct joydev *joydev)
retval = input_open_device(&joydev->handle);
if (retval)
joydev->open--;
else
joydev_refresh_state(joydev);
}
mutex_unlock(&joydev->mutex);
@ -872,7 +885,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
j = joydev->abspam[i];
if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) {
joydev->corr[i].type = JS_CORR_NONE;
joydev->abs[i] = input_abs_get_val(dev, j);
continue;
}
joydev->corr[i].type = JS_CORR_BROKEN;
@ -887,10 +899,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
if (t) {
joydev->corr[i].coef[2] = (1 << 29) / t;
joydev->corr[i].coef[3] = (1 << 29) / t;
joydev->abs[i] =
joydev_correct(input_abs_get_val(dev, j),
joydev->corr + i);
}
}

Просмотреть файл

@ -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)

Просмотреть файл

@ -320,18 +320,18 @@ static struct usb_device_id xpad_table[] = {
XPAD_XBOXONE_VENDOR(0x0738), /* Mad Catz FightStick TE 2 */
XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f X-Box 360 controllers */
XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f X-Box One controllers */
XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOX360_VENDOR(0x12ab), /* X-Box 360 dance pads */
XPAD_XBOX360_VENDOR(0x1430), /* RedOctane X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x146b), /* BigBen Interactive Controllers */
XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
XPAD_XBOX360_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOXONE_VENDOR(0x0f0d), /* Hori Controllers */
XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOX360_VENDOR(0x1532), /* Razer Sabertooth */
XPAD_XBOX360_VENDOR(0x15e4), /* Numark X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x162e), /* Joytech X-Box 360 controllers */
XPAD_XBOX360_VENDOR(0x1689), /* Razer Onza */
XPAD_XBOX360_VENDOR(0x1bad), /* Harminix Rock Band Guitar and Drums */
XPAD_XBOX360_VENDOR(0x24c6), /* PowerA Controllers */
XPAD_XBOXONE_VENDOR(0x24c6), /* PowerA Controllers */
{ }
};
@ -389,6 +389,7 @@ struct usb_xpad {
static int xpad_init_input(struct usb_xpad *xpad);
static void xpad_deinit_input(struct usb_xpad *xpad);
static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num);
/*
* xpad_process_packet
@ -608,14 +609,36 @@ static void xpad360w_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned cha
}
/*
* xpadone_process_buttons
* xpadone_process_packet
*
* Process a button update packet from an Xbox one controller.
* Completes a request by converting the data into events for the
* input subsystem. This version is for the Xbox One controller.
*
* The report format was gleaned from
* https://github.com/kylelemons/xbox/blob/master/xbox.go
*/
static void xpadone_process_buttons(struct usb_xpad *xpad,
struct input_dev *dev,
unsigned char *data)
static void xpadone_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
/* the xbox button has its own special report */
if (data[0] == 0X07) {
/*
* The Xbox One S controller requires these reports to be
* acked otherwise it continues sending them forever and
* won't report further mode button events.
*/
if (data[1] == 0x30)
xpadone_ack_mode_report(xpad, data[2]);
input_report_key(dev, BTN_MODE, data[4] & 0x01);
input_sync(dev);
return;
}
/* check invalid packet */
else if (data[0] != 0X20)
return;
/* menu/view buttons */
input_report_key(dev, BTN_START, data[4] & 0x04);
input_report_key(dev, BTN_SELECT, data[4] & 0x08);
@ -678,34 +701,6 @@ static void xpadone_process_buttons(struct usb_xpad *xpad,
input_sync(dev);
}
/*
* xpadone_process_packet
*
* Completes a request by converting the data into events for the
* input subsystem. This version is for the Xbox One controller.
*
* The report format was gleaned from
* https://github.com/kylelemons/xbox/blob/master/xbox.go
*/
static void xpadone_process_packet(struct usb_xpad *xpad,
u16 cmd, unsigned char *data)
{
struct input_dev *dev = xpad->dev;
switch (data[0]) {
case 0x20:
xpadone_process_buttons(xpad, dev, data);
break;
case 0x07:
/* the xbox button has its own special report */
input_report_key(dev, BTN_MODE, data[4] & 0x01);
input_sync(dev);
break;
}
}
static void xpad_irq_in(struct urb *urb)
{
struct usb_xpad *xpad = urb->context;
@ -850,10 +845,9 @@ static void xpad_irq_out(struct urb *urb)
spin_unlock_irqrestore(&xpad->odata_lock, flags);
}
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad,
struct usb_endpoint_descriptor *ep_irq_out)
{
struct usb_endpoint_descriptor *ep_irq_out;
int ep_irq_out_idx;
int error;
if (xpad->xtype == XTYPE_UNKNOWN)
@ -863,23 +857,17 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
xpad->odata = usb_alloc_coherent(xpad->udev, XPAD_PKT_LEN,
GFP_KERNEL, &xpad->odata_dma);
if (!xpad->odata) {
error = -ENOMEM;
goto fail1;
}
if (!xpad->odata)
return -ENOMEM;
spin_lock_init(&xpad->odata_lock);
xpad->irq_out = usb_alloc_urb(0, GFP_KERNEL);
if (!xpad->irq_out) {
error = -ENOMEM;
goto fail2;
goto err_free_coherent;
}
/* Xbox One controller has in/out endpoints swapped. */
ep_irq_out_idx = xpad->xtype == XTYPE_XBOXONE ? 0 : 1;
ep_irq_out = &intf->cur_altsetting->endpoint[ep_irq_out_idx].desc;
usb_fill_int_urb(xpad->irq_out, xpad->udev,
usb_sndintpipe(xpad->udev, ep_irq_out->bEndpointAddress),
xpad->odata, XPAD_PKT_LEN,
@ -889,8 +877,9 @@ static int xpad_init_output(struct usb_interface *intf, struct usb_xpad *xpad)
return 0;
fail2: usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
fail1: return error;
err_free_coherent:
usb_free_coherent(xpad->udev, XPAD_PKT_LEN, xpad->odata, xpad->odata_dma);
return error;
}
static void xpad_stop_output(struct usb_xpad *xpad)
@ -974,6 +963,30 @@ static int xpad_start_xbox_one(struct usb_xpad *xpad)
return retval;
}
static void xpadone_ack_mode_report(struct usb_xpad *xpad, u8 seq_num)
{
unsigned long flags;
struct xpad_output_packet *packet =
&xpad->out_packets[XPAD_OUT_CMD_IDX];
static const u8 mode_report_ack[] = {
0x01, 0x20, 0x00, 0x09, 0x00, 0x07, 0x20, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00
};
spin_lock_irqsave(&xpad->odata_lock, flags);
packet->len = sizeof(mode_report_ack);
memcpy(packet->data, mode_report_ack, packet->len);
packet->data[2] = seq_num;
packet->pending = true;
/* Reset the sequence so we send out the ack now */
xpad->last_out_packet = -1;
xpad_try_sending_next_out_packet(xpad);
spin_unlock_irqrestore(&xpad->odata_lock, flags);
}
#ifdef CONFIG_JOYSTICK_XPAD_FF
static int xpad_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect)
{
@ -1198,6 +1211,7 @@ static int xpad_led_probe(struct usb_xpad *xpad)
led_cdev = &led->led_cdev;
led_cdev->name = led->name;
led_cdev->brightness_set = xpad_led_set;
led_cdev->flags = LED_CORE_SUSPENDRESUME;
error = led_classdev_register(&xpad->udev->dev, led_cdev);
if (error)
@ -1468,8 +1482,7 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_xpad *xpad;
struct usb_endpoint_descriptor *ep_irq_in;
int ep_irq_in_idx;
struct usb_endpoint_descriptor *ep_irq_in, *ep_irq_out;
int i, error;
if (intf->cur_altsetting->desc.bNumEndpoints != 2)
@ -1539,14 +1552,27 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
goto err_free_in_urb;
}
error = xpad_init_output(intf, xpad);
ep_irq_in = ep_irq_out = NULL;
for (i = 0; i < 2; i++) {
struct usb_endpoint_descriptor *ep =
&intf->cur_altsetting->endpoint[i].desc;
if (usb_endpoint_dir_in(ep))
ep_irq_in = ep;
else
ep_irq_out = ep;
}
if (!ep_irq_in || !ep_irq_out) {
error = -ENODEV;
goto err_free_in_urb;
}
error = xpad_init_output(intf, xpad, ep_irq_out);
if (error)
goto err_free_in_urb;
/* Xbox One controller has in/out endpoints swapped. */
ep_irq_in_idx = xpad->xtype == XTYPE_XBOXONE ? 1 : 0;
ep_irq_in = &intf->cur_altsetting->endpoint[ep_irq_in_idx].desc;
usb_fill_int_urb(xpad->irq_in, udev,
usb_rcvintpipe(udev, ep_irq_in->bEndpointAddress),
xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
@ -1662,8 +1688,16 @@ static int xpad_resume(struct usb_interface *intf)
retval = xpad360w_start_input(xpad);
} else {
mutex_lock(&input->mutex);
if (input->users)
if (input->users) {
retval = xpad_start_input(xpad);
} else if (xpad->xtype == XTYPE_XBOXONE) {
/*
* Even if there are no users, we'll send Xbox One pads
* the startup sequence so they don't sit there and
* blink until somebody opens the input device again.
*/
retval = xpad_start_xbox_one(xpad);
}
mutex_unlock(&input->mutex);
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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

Просмотреть файл

@ -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");

Просмотреть файл

@ -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;

Просмотреть файл

@ -213,7 +213,7 @@ static int bcm_kp_matrix_key_parse_dt(struct bcm_kp *kp)
/* Initialize the KPCR Keypad Configuration Register */
kp->kpcr = KPCR_STATUSFILTERENABLE | KPCR_COLFILTERENABLE;
error = matrix_keypad_parse_of_params(dev, &kp->n_rows, &kp->n_cols);
error = matrix_keypad_parse_properties(dev, &kp->n_rows, &kp->n_cols);
if (error) {
dev_err(dev, "failed to parse kp params\n");
return error;
@ -352,8 +352,6 @@ static int bcm_kp_probe(struct platform_device *pdev)
kp->input_dev = input_dev;
platform_set_drvdata(pdev, kp);
error = bcm_kp_matrix_key_parse_dt(kp);
if (error)
return error;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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)) {

Просмотреть файл

@ -535,7 +535,7 @@ static int cros_ec_keyb_register_matrix(struct cros_ec_keyb *ckdev)
const char *phys;
int err;
err = matrix_keypad_parse_of_params(dev, &ckdev->rows, &ckdev->cols);
err = matrix_keypad_parse_properties(dev, &ckdev->rows, &ckdev->cols);
if (err)
return err;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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) {

Просмотреть файл

@ -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,

Просмотреть файл

@ -145,7 +145,7 @@ static int lpc32xx_parse_dt(struct device *dev,
u32 rows = 0, columns = 0;
int err;
err = matrix_keypad_parse_of_params(dev, &rows, &columns);
err = matrix_keypad_parse_properties(dev, &rows, &columns);
if (err)
return err;
if (rows != columns) {

Просмотреть файл

@ -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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
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);
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");
return -EINVAL;
}
if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
dev_err(&client->dev, "too many keys defined\n");
return -EINVAL;
}
if (!client->irq) {
dev_err(&client->dev, "irq number should not be zero\n");
dev_err(dev, "irq number should not be zero\n");
return -EINVAL;
}
mpr121 = devm_kzalloc(&client->dev, sizeof(*mpr121),
GFP_KERNEL);
vdd_supply = mpr121_vdd_supply_init(dev);
if (IS_ERR(vdd_supply))
return PTR_ERR(vdd_supply);
vdd_uv = regulator_get_voltage(vdd_supply);
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,
error = devm_request_threaded_irq(dev, client->irq, NULL,
mpr_touchkey_interrupt,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
client->dev.driver->name, mpr121);
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,

Просмотреть файл

@ -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,

Просмотреть файл

@ -223,7 +223,7 @@ static int omap4_keypad_parse_dt(struct device *dev,
struct device_node *np = dev->of_node;
int err;
err = matrix_keypad_parse_of_params(dev, &keypad_data->rows,
err = matrix_keypad_parse_properties(dev, &keypad_data->rows,
&keypad_data->cols);
if (err)
return err;
@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -515,7 +515,7 @@ static int pmic8xxx_kp_probe(struct platform_device *pdev)
int rc;
unsigned int ctrl_val;
rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
rc = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols);
if (rc)
return rc;

Просмотреть файл

@ -126,7 +126,7 @@ static int pxa27x_keypad_matrix_key_parse_dt(struct pxa27x_keypad *keypad,
u32 rows, cols;
int error;
error = matrix_keypad_parse_of_params(dev, &rows, &cols);
error = matrix_keypad_parse_properties(dev, &rows, &cols);
if (error)
return error;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -106,7 +106,7 @@ static int keypad_matrix_key_parse_dt(struct st_keyscan *keypad_data)
struct device_node *np = dev->of_node;
int error;
error = matrix_keypad_parse_of_params(dev, &keypad_data->n_rows,
error = matrix_keypad_parse_properties(dev, &keypad_data->n_rows,
&keypad_data->n_cols);
if (error) {
dev_err(dev, "failed to parse keypad params\n");

Просмотреть файл

@ -354,7 +354,7 @@ static int stmpe_keypad_probe(struct platform_device *pdev)
input->id.bustype = BUS_I2C;
input->dev.parent = &pdev->dev;
error = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols);
error = matrix_keypad_parse_properties(&pdev->dev, &rows, &cols);
if (error)
return error;

Просмотреть файл

@ -261,7 +261,6 @@ static int sun4i_lradc_probe(struct platform_device *pdev)
if (error)
return error;
platform_set_drvdata(pdev, lradc);
return 0;
}

Просмотреть файл

@ -24,18 +24,17 @@
* alternative licensing inquiries.
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input.h>
#include <linux/input/tca8418_keypad.h>
#include <linux/input/matrix_keypad.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/types.h>
/* TCA8418 hardware limits */
#define TCA8418_MAX_ROWS 8
@ -267,37 +266,21 @@ static int tca8418_keypad_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
const struct tca8418_keypad_platform_data *pdata =
dev_get_platdata(dev);
struct tca8418_keypad *keypad_data;
struct input_dev *input;
const struct matrix_keymap_data *keymap_data = NULL;
u32 rows = 0, cols = 0;
bool rep = false;
bool irq_is_gpio = false;
int irq;
int error, row_shift, max_keys;
/* Copy the platform data */
if (pdata) {
if (!pdata->keymap_data) {
dev_err(dev, "no keymap data defined\n");
return -EINVAL;
/* Check i2c driver capabilities */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
dev_err(dev, "%s adapter not supported\n",
dev_driver_string(&client->adapter->dev));
return -ENODEV;
}
keymap_data = pdata->keymap_data;
rows = pdata->rows;
cols = pdata->cols;
rep = pdata->rep;
irq_is_gpio = pdata->irq_is_gpio;
} else {
struct device_node *np = dev->of_node;
int err;
err = matrix_keypad_parse_of_params(dev, &rows, &cols);
if (err)
return err;
rep = of_property_read_bool(np, "keypad,autorepeat");
}
error = matrix_keypad_parse_properties(dev, &rows, &cols);
if (error)
return error;
if (!rows || rows > TCA8418_MAX_ROWS) {
dev_err(dev, "invalid rows\n");
@ -309,13 +292,6 @@ static int tca8418_keypad_probe(struct i2c_client *client,
return -EINVAL;
}
/* Check i2c driver capabilities */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) {
dev_err(dev, "%s adapter not supported\n",
dev_driver_string(&client->adapter->dev));
return -ENODEV;
}
row_shift = get_count_order(cols);
max_keys = rows << row_shift;
@ -345,27 +321,20 @@ static int tca8418_keypad_probe(struct i2c_client *client,
input->id.product = 0x001;
input->id.version = 0x0001;
error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols,
NULL, input);
error = matrix_keypad_build_keymap(NULL, NULL, rows, cols, NULL, input);
if (error) {
dev_err(dev, "Failed to build keymap\n");
return error;
}
if (rep)
if (device_property_read_bool(dev, "keypad,autorepeat"))
__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,
error = devm_request_threaded_irq(dev, client->irq,
NULL, tca8418_irq_handler,
IRQF_SHARED | IRQF_ONESHOT,
client->name, keypad_data);
if (error) {
dev_err(dev, "Unable to claim irq %d; error %d\n",
@ -384,30 +353,21 @@ static int tca8418_keypad_probe(struct i2c_client *client,
}
static const struct i2c_device_id tca8418_id[] = {
{ TCA8418_NAME, 8418, },
{ "tca8418", 8418, },
{ }
};
MODULE_DEVICE_TABLE(i2c, tca8418_id);
#ifdef CONFIG_OF
static const struct of_device_id tca8418_dt_ids[] = {
{ .compatible = "ti,tca8418", },
{ }
};
MODULE_DEVICE_TABLE(of, tca8418_dt_ids);
/*
* The device tree based i2c loader looks for
* "i2c:" + second_component_of(property("compatible"))
* and therefore we need an alias to be found.
*/
MODULE_ALIAS("i2c:tca8418");
#endif
static struct i2c_driver tca8418_keypad_driver = {
.driver = {
.name = TCA8418_NAME,
.of_match_table = of_match_ptr(tca8418_dt_ids),
.name = "tca8418_keypad",
.of_match_table = tca8418_dt_ids,
},
.probe = tca8418_keypad_probe,
.id_table = tca8418_id,

Просмотреть файл

@ -0,0 +1,284 @@
/*
* TM2 touchkey device driver
*
* Copyright 2005 Phil Blundell
* Copyright 2016 Samsung Electronics Co., Ltd.
*
* Author: Beomho Seo <beomho.seo@samsung.com>
* Author: Jaechul Lee <jcsing.lee@samsung.com>
*
* 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 <beomho.seo@samsung.com>");
MODULE_AUTHOR("Jaechul Lee <jcsing.lee@samsung.com>");
MODULE_DESCRIPTION("Samsung touchkey driver");
MODULE_LICENSE("GPL v2");

Просмотреть файл

@ -374,7 +374,7 @@ static int twl4030_kp_probe(struct platform_device *pdev)
kp->autorepeat = pdata->rep;
keymap_data = pdata->keymap_data;
} else {
error = matrix_keypad_parse_of_params(&pdev->dev, &kp->n_rows,
error = matrix_keypad_parse_properties(&pdev->dev, &kp->n_rows,
&kp->n_cols);
if (error)
return error;
@ -441,7 +441,6 @@ static int twl4030_kp_probe(struct platform_device *pdev)
return -EIO;
}
platform_set_drvdata(pdev, kp);
return 0;
}

Просмотреть файл

@ -14,18 +14,18 @@
* 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.
*
*/
#include <linux/device.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/input.h>
#include <linux/of.h>
#include <linux/export.h>
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/property.h>
#include <linux/slab.h>
#include <linux/types.h>
static bool matrix_keypad_map_key(struct input_dev *input_dev,
unsigned int rows, unsigned int cols,
@ -49,18 +49,22 @@ static bool matrix_keypad_map_key(struct input_dev *input_dev,
return true;
}
#ifdef CONFIG_OF
int matrix_keypad_parse_of_params(struct device *dev,
/**
* matrix_keypad_parse_properties() - Read properties of matrix keypad
*
* @dev: Device containing properties
* @rows: Returns number of matrix rows
* @cols: Returns number of matrix columns
* @return 0 if OK, <0 on error
*/
int matrix_keypad_parse_properties(struct device *dev,
unsigned int *rows, unsigned int *cols)
{
struct device_node *np = dev->of_node;
*rows = *cols = 0;
device_property_read_u32(dev, "keypad,num-rows", rows);
device_property_read_u32(dev, "keypad,num-columns", cols);
if (!np) {
dev_err(dev, "missing DT data");
return -EINVAL;
}
of_property_read_u32(np, "keypad,num-rows", rows);
of_property_read_u32(np, "keypad,num-columns", cols);
if (!*rows || !*cols) {
dev_err(dev, "number of keypad rows/columns not specified\n");
return -EINVAL;
@ -68,62 +72,61 @@ int matrix_keypad_parse_of_params(struct device *dev,
return 0;
}
EXPORT_SYMBOL_GPL(matrix_keypad_parse_of_params);
EXPORT_SYMBOL_GPL(matrix_keypad_parse_properties);
static int matrix_keypad_parse_of_keymap(const char *propname,
static int matrix_keypad_parse_keymap(const char *propname,
unsigned int rows, unsigned int cols,
struct input_dev *input_dev)
{
struct device *dev = input_dev->dev.parent;
struct device_node *np = dev->of_node;
unsigned int row_shift = get_count_order(cols);
unsigned int max_keys = rows << row_shift;
unsigned int proplen, i, size;
const __be32 *prop;
if (!np)
return -ENOENT;
u32 *keys;
int i;
int size;
int retval;
if (!propname)
propname = "linux,keymap";
prop = of_get_property(np, propname, &proplen);
if (!prop) {
dev_err(dev, "OF: %s property not defined in %s\n",
propname, np->full_name);
return -ENOENT;
size = device_property_read_u32_array(dev, propname, NULL, 0);
if (size <= 0) {
dev_err(dev, "missing or malformed property %s: %d\n",
propname, size);
return size < 0 ? size : -EINVAL;
}
if (proplen % sizeof(u32)) {
dev_err(dev, "OF: Malformed keycode property %s in %s\n",
propname, np->full_name);
return -EINVAL;
}
size = proplen / sizeof(u32);
if (size > max_keys) {
dev_err(dev, "OF: %s size overflow\n", propname);
dev_err(dev, "%s size overflow (%d vs max %u)\n",
propname, size, max_keys);
return -EINVAL;
}
keys = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
if (!keys)
return -ENOMEM;
retval = device_property_read_u32_array(dev, propname, keys, size);
if (retval) {
dev_err(dev, "failed to read %s property: %d\n",
propname, retval);
goto out;
}
for (i = 0; i < size; i++) {
unsigned int key = be32_to_cpup(prop + i);
if (!matrix_keypad_map_key(input_dev, rows, cols,
row_shift, key))
return -EINVAL;
row_shift, keys[i])) {
retval = -EINVAL;
goto out;
}
}
return 0;
retval = 0;
out:
kfree(keys);
return retval;
}
#else
static int matrix_keypad_parse_of_keymap(const char *propname,
unsigned int rows, unsigned int cols,
struct input_dev *input_dev)
{
return -ENOSYS;
}
#endif
/**
* matrix_keypad_build_keymap - convert platform keymap into matrix keymap
@ -192,7 +195,7 @@ int matrix_keypad_build_keymap(const struct matrix_keymap_data *keymap_data,
return -EINVAL;
}
} else {
error = matrix_keypad_parse_of_keymap(keymap_name, rows, cols,
error = matrix_keypad_parse_keymap(keymap_name, rows, cols,
input_dev);
if (error)
return error;

Просмотреть файл

@ -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);

Просмотреть файл

@ -234,16 +234,6 @@ config INPUT_MMA8450
To compile this driver as a module, choose M here: the
module will be called mma8450.
config INPUT_MPU3050
tristate "MPU3050 Triaxial gyroscope sensor"
depends on I2C
help
Say Y here if you want to support InvenSense MPU3050
connected via an I2C bus.
To compile this driver as a module, choose M here: the
module will be called mpu3050.
config INPUT_APANEL
tristate "Fujitsu Lifebook Application Panel buttons"
depends on X86 && I2C && LEDS_CLASS

Просмотреть файл

@ -48,7 +48,6 @@ obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o
obj-$(CONFIG_INPUT_MAX8997_HAPTIC) += max8997_haptic.o
obj-$(CONFIG_INPUT_MC13783_PWRBUTTON) += mc13783-pwrbutton.o
obj-$(CONFIG_INPUT_MMA8450) += mma8450.o
obj-$(CONFIG_INPUT_MPU3050) += mpu3050.o
obj-$(CONFIG_INPUT_PALMAS_PWRBUTTON) += palmas-pwrbutton.o
obj-$(CONFIG_INPUT_PCAP) += pcap_keys.o
obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o

Просмотреть файл

@ -109,7 +109,6 @@ static int ab8500_ponkey_probe(struct platform_device *pdev)
return error;
}
platform_set_drvdata(pdev, ponkey);
return 0;
}

Просмотреть файл

@ -201,8 +201,6 @@ static int arizona_haptics_probe(struct platform_device *pdev)
return ret;
}
platform_set_drvdata(pdev, haptics);
return 0;
}

Просмотреть файл

@ -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));

Просмотреть файл

@ -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,
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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -287,7 +287,6 @@ static int da9063_onkey_probe(struct platform_device *pdev)
return error;
}
platform_set_drvdata(pdev, onkey);
return 0;
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -205,8 +205,6 @@ static int mma8450_probe(struct i2c_client *c,
return err;
}
i2c_set_clientdata(c, m);
return 0;
}

Просмотреть файл

@ -1,481 +0,0 @@
/*
* MPU3050 Tri-axis gyroscope driver
*
* Copyright (C) 2011 Wistron Co.Ltd
* Joseph Lai <joseph_lai@wistron.com>
*
* Trimmed down by Alan Cox <alan@linux.intel.com> to produce this version
*
* This is a 'lite' version of the driver, while we consider the right way
* to present the other features to user space. In particular it requires the
* device has an IRQ, and it only provides an input interface, so is not much
* use for device orientation. A fuller version is available from the Meego
* tree.
*
* This program is based on bma023.c.
*
* 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.
*
*/
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
#define MPU3050_CHIP_ID 0x69
#define MPU3050_AUTO_DELAY 1000
#define MPU3050_MIN_VALUE -32768
#define MPU3050_MAX_VALUE 32767
#define MPU3050_DEFAULT_POLL_INTERVAL 200
#define MPU3050_DEFAULT_FS_RANGE 3
/* Register map */
#define MPU3050_CHIP_ID_REG 0x00
#define MPU3050_SMPLRT_DIV 0x15
#define MPU3050_DLPF_FS_SYNC 0x16
#define MPU3050_INT_CFG 0x17
#define MPU3050_XOUT_H 0x1D
#define MPU3050_PWR_MGM 0x3E
#define MPU3050_PWR_MGM_POS 6
/* Register bits */
/* DLPF_FS_SYNC */
#define MPU3050_EXT_SYNC_NONE 0x00
#define MPU3050_EXT_SYNC_TEMP 0x20
#define MPU3050_EXT_SYNC_GYROX 0x40
#define MPU3050_EXT_SYNC_GYROY 0x60
#define MPU3050_EXT_SYNC_GYROZ 0x80
#define MPU3050_EXT_SYNC_ACCELX 0xA0
#define MPU3050_EXT_SYNC_ACCELY 0xC0
#define MPU3050_EXT_SYNC_ACCELZ 0xE0
#define MPU3050_EXT_SYNC_MASK 0xE0
#define MPU3050_FS_250DPS 0x00
#define MPU3050_FS_500DPS 0x08
#define MPU3050_FS_1000DPS 0x10
#define MPU3050_FS_2000DPS 0x18
#define MPU3050_FS_MASK 0x18
#define MPU3050_DLPF_CFG_256HZ_NOLPF2 0x00
#define MPU3050_DLPF_CFG_188HZ 0x01
#define MPU3050_DLPF_CFG_98HZ 0x02
#define MPU3050_DLPF_CFG_42HZ 0x03
#define MPU3050_DLPF_CFG_20HZ 0x04
#define MPU3050_DLPF_CFG_10HZ 0x05
#define MPU3050_DLPF_CFG_5HZ 0x06
#define MPU3050_DLPF_CFG_2100HZ_NOLPF 0x07
#define MPU3050_DLPF_CFG_MASK 0x07
/* INT_CFG */
#define MPU3050_RAW_RDY_EN 0x01
#define MPU3050_MPU_RDY_EN 0x02
#define MPU3050_LATCH_INT_EN 0x04
/* PWR_MGM */
#define MPU3050_PWR_MGM_PLL_X 0x01
#define MPU3050_PWR_MGM_PLL_Y 0x02
#define MPU3050_PWR_MGM_PLL_Z 0x03
#define MPU3050_PWR_MGM_CLKSEL 0x07
#define MPU3050_PWR_MGM_STBY_ZG 0x08
#define MPU3050_PWR_MGM_STBY_YG 0x10
#define MPU3050_PWR_MGM_STBY_XG 0x20
#define MPU3050_PWR_MGM_SLEEP 0x40
#define MPU3050_PWR_MGM_RESET 0x80
#define MPU3050_PWR_MGM_MASK 0x40
struct axis_data {
s16 x;
s16 y;
s16 z;
};
struct mpu3050_sensor {
struct i2c_client *client;
struct device *dev;
struct input_dev *idev;
};
/**
* mpu3050_xyz_read_reg - read the axes values
* @buffer: provide register addr and get register
* @length: length of register
*
* Reads the register values in one transaction or returns a negative
* error code on failure.
*/
static int mpu3050_xyz_read_reg(struct i2c_client *client,
u8 *buffer, int length)
{
/*
* Annoying we can't make this const because the i2c layer doesn't
* declare input buffers const.
*/
char cmd = MPU3050_XOUT_H;
struct i2c_msg msg[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = &cmd,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = length,
.buf = buffer,
},
};
return i2c_transfer(client->adapter, msg, 2);
}
/**
* mpu3050_read_xyz - get co-ordinates from device
* @client: i2c address of sensor
* @coords: co-ordinates to update
*
* Return the converted X Y and Z co-ordinates from the sensor device
*/
static void mpu3050_read_xyz(struct i2c_client *client,
struct axis_data *coords)
{
u16 buffer[3];
mpu3050_xyz_read_reg(client, (u8 *)buffer, 6);
coords->x = be16_to_cpu(buffer[0]);
coords->y = be16_to_cpu(buffer[1]);
coords->z = be16_to_cpu(buffer[2]);
dev_dbg(&client->dev, "%s: x %d, y %d, z %d\n", __func__,
coords->x, coords->y, coords->z);
}
/**
* mpu3050_set_power_mode - set the power mode
* @client: i2c client for the sensor
* @val: value to switch on/off of power, 1: normal power, 0: low power
*
* Put device to normal-power mode or low-power mode.
*/
static void mpu3050_set_power_mode(struct i2c_client *client, u8 val)
{
u8 value;
value = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
value = (value & ~MPU3050_PWR_MGM_MASK) |
(((val << MPU3050_PWR_MGM_POS) & MPU3050_PWR_MGM_MASK) ^
MPU3050_PWR_MGM_MASK);
i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, value);
}
/**
* mpu3050_input_open - called on input event open
* @input: input dev of opened device
*
* The input layer calls this function when input event is opened. The
* function will push the device to resume. Then, the device is ready
* to provide data.
*/
static int mpu3050_input_open(struct input_dev *input)
{
struct mpu3050_sensor *sensor = input_get_drvdata(input);
int error;
pm_runtime_get(sensor->dev);
/* Enable interrupts */
error = i2c_smbus_write_byte_data(sensor->client, MPU3050_INT_CFG,
MPU3050_LATCH_INT_EN |
MPU3050_RAW_RDY_EN |
MPU3050_MPU_RDY_EN);
if (error < 0) {
pm_runtime_put(sensor->dev);
return error;
}
return 0;
}
/**
* mpu3050_input_close - called on input event close
* @input: input dev of closed device
*
* The input layer calls this function when input event is closed. The
* function will push the device to suspend.
*/
static void mpu3050_input_close(struct input_dev *input)
{
struct mpu3050_sensor *sensor = input_get_drvdata(input);
pm_runtime_put(sensor->dev);
}
/**
* mpu3050_interrupt_thread - handle an IRQ
* @irq: interrupt numner
* @data: the sensor
*
* Called by the kernel single threaded after an interrupt occurs. Read
* the sensor data and generate an input event for it.
*/
static irqreturn_t mpu3050_interrupt_thread(int irq, void *data)
{
struct mpu3050_sensor *sensor = data;
struct axis_data axis;
mpu3050_read_xyz(sensor->client, &axis);
input_report_abs(sensor->idev, ABS_X, axis.x);
input_report_abs(sensor->idev, ABS_Y, axis.y);
input_report_abs(sensor->idev, ABS_Z, axis.z);
input_sync(sensor->idev);
return IRQ_HANDLED;
}
/**
* mpu3050_hw_init - initialize hardware
* @sensor: the sensor
*
* Called during device probe; configures the sampling method.
*/
static int mpu3050_hw_init(struct mpu3050_sensor *sensor)
{
struct i2c_client *client = sensor->client;
int ret;
u8 reg;
/* Reset */
ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM,
MPU3050_PWR_MGM_RESET);
if (ret < 0)
return ret;
ret = i2c_smbus_read_byte_data(client, MPU3050_PWR_MGM);
if (ret < 0)
return ret;
ret &= ~MPU3050_PWR_MGM_CLKSEL;
ret |= MPU3050_PWR_MGM_PLL_Z;
ret = i2c_smbus_write_byte_data(client, MPU3050_PWR_MGM, ret);
if (ret < 0)
return ret;
/* Output frequency divider. The poll interval */
ret = i2c_smbus_write_byte_data(client, MPU3050_SMPLRT_DIV,
MPU3050_DEFAULT_POLL_INTERVAL - 1);
if (ret < 0)
return ret;
/* Set low pass filter and full scale */
reg = MPU3050_DEFAULT_FS_RANGE;
reg |= MPU3050_DLPF_CFG_42HZ << 3;
reg |= MPU3050_EXT_SYNC_NONE << 5;
ret = i2c_smbus_write_byte_data(client, MPU3050_DLPF_FS_SYNC, reg);
if (ret < 0)
return ret;
return 0;
}
/**
* mpu3050_probe - device detection callback
* @client: i2c client of found device
* @id: id match information
*
* The I2C layer calls us when it believes a sensor is present at this
* address. Probe to see if this is correct and to validate the device.
*
* If present install the relevant sysfs interfaces and input device.
*/
static int mpu3050_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct mpu3050_sensor *sensor;
struct input_dev *idev;
int ret;
int error;
sensor = kzalloc(sizeof(struct mpu3050_sensor), GFP_KERNEL);
idev = input_allocate_device();
if (!sensor || !idev) {
dev_err(&client->dev, "failed to allocate driver data\n");
error = -ENOMEM;
goto err_free_mem;
}
sensor->client = client;
sensor->dev = &client->dev;
sensor->idev = idev;
mpu3050_set_power_mode(client, 1);
msleep(10);
ret = i2c_smbus_read_byte_data(client, MPU3050_CHIP_ID_REG);
if (ret < 0) {
dev_err(&client->dev, "failed to detect device\n");
error = -ENXIO;
goto err_free_mem;
}
if (ret != MPU3050_CHIP_ID) {
dev_err(&client->dev, "unsupported chip id\n");
error = -ENXIO;
goto err_free_mem;
}
idev->name = "MPU3050";
idev->id.bustype = BUS_I2C;
idev->dev.parent = &client->dev;
idev->open = mpu3050_input_open;
idev->close = mpu3050_input_close;
__set_bit(EV_ABS, idev->evbit);
input_set_abs_params(idev, ABS_X,
MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
input_set_abs_params(idev, ABS_Y,
MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
input_set_abs_params(idev, ABS_Z,
MPU3050_MIN_VALUE, MPU3050_MAX_VALUE, 0, 0);
input_set_drvdata(idev, sensor);
pm_runtime_set_active(&client->dev);
error = mpu3050_hw_init(sensor);
if (error)
goto err_pm_set_suspended;
error = request_threaded_irq(client->irq,
NULL, mpu3050_interrupt_thread,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"mpu3050", sensor);
if (error) {
dev_err(&client->dev,
"can't get IRQ %d, error %d\n", client->irq, error);
goto err_pm_set_suspended;
}
error = input_register_device(idev);
if (error) {
dev_err(&client->dev, "failed to register input device\n");
goto err_free_irq;
}
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev, MPU3050_AUTO_DELAY);
i2c_set_clientdata(client, sensor);
return 0;
err_free_irq:
free_irq(client->irq, sensor);
err_pm_set_suspended:
pm_runtime_set_suspended(&client->dev);
err_free_mem:
input_free_device(idev);
kfree(sensor);
return error;
}
/**
* mpu3050_remove - remove a sensor
* @client: i2c client of sensor being removed
*
* Our sensor is going away, clean up the resources.
*/
static int mpu3050_remove(struct i2c_client *client)
{
struct mpu3050_sensor *sensor = i2c_get_clientdata(client);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
free_irq(client->irq, sensor);
input_unregister_device(sensor->idev);
kfree(sensor);
return 0;
}
#ifdef CONFIG_PM
/**
* mpu3050_suspend - called on device suspend
* @dev: device being suspended
*
* Put the device into sleep mode before we suspend the machine.
*/
static int mpu3050_suspend(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
mpu3050_set_power_mode(client, 0);
return 0;
}
/**
* mpu3050_resume - called on device resume
* @dev: device being resumed
*
* Put the device into powered mode on resume.
*/
static int mpu3050_resume(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
mpu3050_set_power_mode(client, 1);
msleep(100); /* wait for gyro chip resume */
return 0;
}
#endif
static UNIVERSAL_DEV_PM_OPS(mpu3050_pm, mpu3050_suspend, mpu3050_resume, NULL);
static const struct i2c_device_id mpu3050_ids[] = {
{ "mpu3050", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, mpu3050_ids);
static const struct of_device_id mpu3050_of_match[] = {
{ .compatible = "invn,mpu3050", },
{ },
};
MODULE_DEVICE_TABLE(of, mpu3050_of_match);
static struct i2c_driver mpu3050_i2c_driver = {
.driver = {
.name = "mpu3050",
.pm = &mpu3050_pm,
.of_match_table = mpu3050_of_match,
},
.probe = mpu3050_probe,
.remove = mpu3050_remove,
.id_table = mpu3050_ids,
};
module_i2c_driver(mpu3050_i2c_driver);
MODULE_AUTHOR("Wistron Corp.");
MODULE_DESCRIPTION("MPU3050 Tri-axis gyroscope driver");
MODULE_LICENSE("GPL");

Просмотреть файл

@ -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;

Просмотреть файл

@ -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",

Просмотреть файл

@ -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;
}
static void pwm_beeper_off(struct pwm_beeper *beeper)
{
if (beeper->amplifier_on) {
regulator_disable(beeper->amplifier);
beeper->amplifier_on = false;
}
if (period) {
pwm_config(beeper->pwm, period / 2, period);
pwm_enable(beeper->pwm);
} else
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,6 +107,7 @@ static int pwm_beeper_event(struct input_dev *input,
else
beeper->period = HZ_TO_NANOSECONDS(value);
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);
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");
}
beeper->pwm = devm_pwm_get(dev, NULL);
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;
if (error != -EPROBE_DEFER)
dev_err(dev, "Failed to request PWM device: %d\n",
error);
return error;
}
/*
* FIXME: pwm_apply_args() should be removed when switching to
* the atomic PWM API.
*/
pwm_apply_args(beeper->pwm);
/* 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;
}
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,34 +190,12 @@ 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;
}
@ -183,6 +203,15 @@ 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,

Просмотреть файл

@ -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",
},

Просмотреть файл

@ -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,

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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)

Просмотреть файл

@ -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);

Просмотреть файл

@ -832,7 +832,7 @@ static int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
int error;
if (device_can_wakeup(dev)) {
error = sysfs_merge_group(&client->dev.kobj,
error = sysfs_merge_group(&dev->kobj,
&cyapa_power_wakeup_group);
if (error) {
dev_err(dev, "failed to add power wakeup group: %d\n",
@ -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;

Просмотреть файл

@ -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");
out:
return ret < 0 ? ret : count;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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) ||

Просмотреть файл

@ -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;

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);

Просмотреть файл

@ -127,6 +127,13 @@ struct psmouse_protocol {
int (*init)(struct psmouse *);
};
static void psmouse_report_standard_buttons(struct input_dev *dev, u8 buttons)
{
input_report_key(dev, BTN_LEFT, buttons & BIT(0));
input_report_key(dev, BTN_MIDDLE, buttons & BIT(2));
input_report_key(dev, BTN_RIGHT, buttons & BIT(1));
}
/*
* psmouse_process_byte() analyzes the PS/2 data stream and reports
* relevant events to the input module once full packet has arrived.
@ -199,9 +206,8 @@ psmouse_ret_t psmouse_process_byte(struct psmouse *psmouse)
}
/* Generic PS/2 Mouse */
input_report_key(dev, BTN_LEFT, packet[0] & 1);
input_report_key(dev, BTN_MIDDLE, (packet[0] >> 2) & 1);
input_report_key(dev, BTN_RIGHT, (packet[0] >> 1) & 1);
psmouse_report_standard_buttons(dev,
packet[0] | psmouse->extra_buttons);
input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0);
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);
@ -282,6 +288,30 @@ static int psmouse_handle_byte(struct psmouse *psmouse)
return 0;
}
static void psmouse_handle_oob_data(struct psmouse *psmouse, u8 data)
{
switch (psmouse->oob_data_type) {
case PSMOUSE_OOB_NONE:
psmouse->oob_data_type = data;
break;
case PSMOUSE_OOB_EXTRA_BTNS:
psmouse_report_standard_buttons(psmouse->dev, data);
input_sync(psmouse->dev);
psmouse->extra_buttons = data;
psmouse->oob_data_type = PSMOUSE_OOB_NONE;
break;
default:
psmouse_warn(psmouse,
"unknown OOB_DATA type: 0x%02x\n",
psmouse->oob_data_type);
psmouse->oob_data_type = PSMOUSE_OOB_NONE;
break;
}
}
/*
* psmouse_interrupt() handles incoming characters, either passing them
* for normal processing or gathering them as command response.
@ -306,6 +336,11 @@ static irqreturn_t psmouse_interrupt(struct serio *serio,
goto out;
}
if (flags & SERIO_OOB_DATA) {
psmouse_handle_oob_data(psmouse, data);
goto out;
}
if (unlikely(psmouse->ps2dev.flags & PS2_FLAG_ACK))
if (ps2_handle_ack(&psmouse->ps2dev, data))
goto out;

Просмотреть файл

@ -1,6 +1,9 @@
#ifndef _PSMOUSE_H
#define _PSMOUSE_H
#define PSMOUSE_OOB_NONE 0x00
#define PSMOUSE_OOB_EXTRA_BTNS 0x01
#define PSMOUSE_CMD_SETSCALE11 0x00e6
#define PSMOUSE_CMD_SETSCALE21 0x00e7
#define PSMOUSE_CMD_SETRES 0x10e8
@ -53,6 +56,8 @@ struct psmouse {
unsigned char pktcnt;
unsigned char pktsize;
unsigned char type;
unsigned char oob_data_type;
unsigned char extra_buttons;
bool ignore_parity;
bool acks_disable_command;
unsigned int model;

Просмотреть файл

@ -597,15 +597,13 @@ static int synaptics_is_pt_packet(unsigned char *buf)
return (buf[0] & 0xFC) == 0x84 && (buf[3] & 0xCC) == 0xC4;
}
static void synaptics_pass_pt_packet(struct psmouse *psmouse,
struct serio *ptport,
static void synaptics_pass_pt_packet(struct serio *ptport,
unsigned char *packet)
{
struct synaptics_data *priv = psmouse->private;
struct psmouse *child = serio_get_drvdata(ptport);
if (child && child->state == PSMOUSE_ACTIVATED) {
serio_interrupt(ptport, packet[1] | priv->pt_buttons, 0);
serio_interrupt(ptport, packet[1], 0);
serio_interrupt(ptport, packet[4], 0);
serio_interrupt(ptport, packet[5], 0);
if (child->pktsize == 4)
@ -856,7 +854,6 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse,
struct input_dev *dev = psmouse->dev;
struct synaptics_data *priv = psmouse->private;
int ext_bits = (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) + 1) >> 1;
char buf[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int i;
if (!SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap))
@ -883,15 +880,18 @@ static void synaptics_report_ext_buttons(struct psmouse *psmouse,
* physically wired to the touchpad. Re-route them through
* the pass-through interface.
*/
if (!priv->pt_port)
return;
if (priv->pt_port) {
u8 pt_buttons;
/* The trackstick expects at most 3 buttons */
priv->pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) |
pt_buttons = SYN_CAP_EXT_BUTTON_STICK_L(hw->ext_buttons) |
SYN_CAP_EXT_BUTTON_STICK_R(hw->ext_buttons) << 1 |
SYN_CAP_EXT_BUTTON_STICK_M(hw->ext_buttons) << 2;
synaptics_pass_pt_packet(psmouse, priv->pt_port, buf);
serio_interrupt(priv->pt_port,
PSMOUSE_OOB_EXTRA_BTNS, SERIO_OOB_DATA);
serio_interrupt(priv->pt_port, pt_buttons, SERIO_OOB_DATA);
}
}
static void synaptics_report_buttons(struct psmouse *psmouse,
@ -1132,7 +1132,7 @@ static psmouse_ret_t synaptics_process_byte(struct psmouse *psmouse)
if (SYN_CAP_PASS_THROUGH(priv->capabilities) &&
synaptics_is_pt_packet(psmouse->packet)) {
if (priv->pt_port)
synaptics_pass_pt_packet(psmouse, priv->pt_port,
synaptics_pass_pt_packet(priv->pt_port,
psmouse->packet);
} else
synaptics_process_packet(psmouse);

Просмотреть файл

@ -183,7 +183,6 @@ struct synaptics_data {
bool disable_gesture; /* disable gestures */
struct serio *pt_port; /* Pass-through serio port */
unsigned char pt_buttons; /* Pass-through buttons */
/*
* Last received Advanced Gesture Mode (AGM) packet. An AGM packet

Просмотреть файл

@ -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)

Просмотреть файл

@ -9,9 +9,11 @@ config RMI4_CORE
If unsure, say Y.
if RMI4_CORE
config RMI4_I2C
tristate "RMI4 I2C Support"
depends on RMI4_CORE && I2C
depends on I2C
help
Say Y here if you want to support RMI4 devices connected to an I2C
bus.
@ -20,7 +22,7 @@ config RMI4_I2C
config RMI4_SPI
tristate "RMI4 SPI Support"
depends on RMI4_CORE && SPI
depends on SPI
help
Say Y here if you want to support RMI4 devices connected to a SPI
bus.
@ -29,7 +31,7 @@ config RMI4_SPI
config RMI4_SMB
tristate "RMI4 SMB Support"
depends on RMI4_CORE && I2C
depends on I2C
help
Say Y here if you want to support RMI4 devices connected to an SMB
bus.
@ -57,12 +59,10 @@ config RMI4_F03_SERIO
config RMI4_2D_SENSOR
bool
depends on RMI4_CORE
config RMI4_F11
bool "RMI4 Function 11 (2D pointing)"
select RMI4_2D_SENSOR
depends on RMI4_CORE
help
Say Y here if you want to add support for RMI4 function 11.
@ -73,7 +73,6 @@ config RMI4_F11
config RMI4_F12
bool "RMI4 Function 12 (2D pointing)"
select RMI4_2D_SENSOR
depends on RMI4_CORE
help
Say Y here if you want to add support for RMI4 function 12.
@ -83,7 +82,6 @@ config RMI4_F12
config RMI4_F30
bool "RMI4 Function 30 (GPIO LED)"
depends on RMI4_CORE
help
Say Y here if you want to add support for RMI4 function 30.
@ -92,7 +90,6 @@ config RMI4_F30
config RMI4_F34
bool "RMI4 Function 34 (Device reflash)"
depends on RMI4_CORE
select FW_LOADER
help
Say Y here if you want to add support for RMI4 function 34.
@ -103,7 +100,6 @@ config RMI4_F34
config RMI4_F54
bool "RMI4 Function 54 (Analog diagnostics)"
depends on RMI4_CORE
depends on VIDEO_V4L2=y || (RMI4_CORE=m && VIDEO_V4L2=m)
select VIDEOBUF2_VMALLOC
select RMI4_F55
@ -115,9 +111,10 @@ config RMI4_F54
config RMI4_F55
bool "RMI4 Function 55 (Sensor tuning)"
depends on RMI4_CORE
help
Say Y here if you want to add support for RMI4 function 55
Function 55 provides access to the RMI4 touch sensor tuning
mechanism.
endif # RMI_CORE

Просмотреть файл

@ -144,8 +144,13 @@ static void rmi_2d_sensor_set_input_params(struct rmi_2d_sensor *sensor)
int input_flags = 0;
if (sensor->report_abs) {
if (sensor->axis_align.swap_axes)
if (sensor->axis_align.swap_axes) {
swap(sensor->max_x, sensor->max_y);
swap(sensor->axis_align.clip_x_low,
sensor->axis_align.clip_y_low);
swap(sensor->axis_align.clip_x_high,
sensor->axis_align.clip_y_high);
}
sensor->min_x = sensor->axis_align.clip_x_low;
if (sensor->axis_align.clip_x_high)

Просмотреть файл

@ -55,7 +55,7 @@ static void rmi_release_device(struct device *dev)
kfree(rmi_dev);
}
static struct device_type rmi_device_type = {
static const struct device_type rmi_device_type = {
.name = "rmi4_sensor",
.release = rmi_release_device,
};
@ -134,7 +134,7 @@ static void rmi_release_function(struct device *dev)
kfree(fn);
}
static struct device_type rmi_function_type = {
static const struct device_type rmi_function_type = {
.name = "rmi4_function",
.release = rmi_release_function,
};
@ -261,10 +261,10 @@ int __rmi_register_function_handler(struct rmi_function_handler *handler,
driver->probe = rmi_function_probe;
driver->remove = rmi_function_remove;
error = driver_register(&handler->driver);
error = driver_register(driver);
if (error) {
pr_err("driver_register() failed for %s, error: %d\n",
handler->driver.name, error);
driver->name, error);
return error;
}

Просмотреть файл

@ -265,6 +265,19 @@ static int rmi_irq_init(struct rmi_device *rmi_dev)
return 0;
}
struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
struct rmi_function *entry;
list_for_each_entry(entry, &data->function_list, node) {
if (entry->fd.function_number == number)
return entry;
}
return NULL;
}
static int suspend_one_function(struct rmi_function *fn)
{
struct rmi_function_handler *fh;
@ -364,7 +377,7 @@ static void rmi_driver_set_input_name(struct rmi_device *rmi_dev,
struct input_dev *input)
{
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
char *device_name = rmi_f01_get_product_ID(data->f01_container);
const char *device_name = rmi_f01_get_product_ID(data->f01_container);
char *name;
name = devm_kasprintf(&rmi_dev->dev, GFP_KERNEL,
@ -836,7 +849,7 @@ static int rmi_create_function(struct rmi_device *rmi_dev,
void *ctx, const struct pdt_entry *pdt)
{
struct device *dev = &rmi_dev->dev;
struct rmi_driver_data *data = dev_get_drvdata(&rmi_dev->dev);
struct rmi_driver_data *data = dev_get_drvdata(dev);
int *current_irq_count = ctx;
struct rmi_function *fn;
int i;
@ -1040,7 +1053,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
}
if (data->bootloader_mode)
dev_warn(&rmi_dev->dev, "Device in bootloader mode.\n");
dev_warn(dev, "Device in bootloader mode.\n");
data->irq_count = irq_count;
data->num_of_irq_regs = (data->irq_count + 7) / 8;
@ -1049,7 +1062,7 @@ int rmi_probe_interrupts(struct rmi_driver_data *data)
data->irq_memory = devm_kzalloc(dev, size * 4, GFP_KERNEL);
if (!data->irq_memory) {
dev_err(dev, "Failed to allocate memory for irq masks.\n");
return retval;
return -ENOMEM;
}
data->irq_status = data->irq_memory + size * 0;

Просмотреть файл

@ -93,6 +93,7 @@ bool rmi_is_physical_driver(struct device_driver *);
int rmi_register_physical_driver(void);
void rmi_unregister_physical_driver(void);
void rmi_free_function_list(struct rmi_device *rmi_dev);
struct rmi_function *rmi_find_function(struct rmi_device *rmi_dev, u8 number);
int rmi_enable_sensor(struct rmi_device *rmi_dev);
int rmi_scan_pdt(struct rmi_device *rmi_dev, void *ctx,
int (*callback)(struct rmi_device *rmi_dev, void *ctx,
@ -104,7 +105,20 @@ int rmi_init_functions(struct rmi_driver_data *data);
int rmi_initial_reset(struct rmi_device *rmi_dev, void *ctx,
const struct pdt_entry *pdt);
char *rmi_f01_get_product_ID(struct rmi_function *fn);
const char *rmi_f01_get_product_ID(struct rmi_function *fn);
#ifdef CONFIG_RMI4_F03
int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
int value);
void rmi_f03_commit_buttons(struct rmi_function *fn);
#else
static inline int rmi_f03_overwrite_button(struct rmi_function *fn,
unsigned int button, int value)
{
return 0;
}
static inline void rmi_f03_commit_buttons(struct rmi_function *fn) {}
#endif
#ifdef CONFIG_RMI4_F34
int rmi_f34_create_sysfs(struct rmi_device *rmi_dev);

Просмотреть файл

@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/of.h>
#include <asm/unaligned.h>
#include "rmi_driver.h"
#define RMI_PRODUCT_ID_LENGTH 10
@ -54,6 +55,7 @@ struct f01_basic_properties {
u8 product_id[RMI_PRODUCT_ID_LENGTH + 1];
u16 productinfo;
u32 firmware_id;
u32 package_id;
};
/* F01 device status bits */
@ -220,8 +222,19 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
has_build_id_query = !!(queries[0] & BIT(1));
}
if (has_package_id_query)
if (has_package_id_query) {
ret = rmi_read_block(rmi_dev, prod_info_addr,
queries, sizeof(__le64));
if (ret) {
dev_err(&rmi_dev->dev,
"Failed to read package info: %d\n",
ret);
return ret;
}
props->package_id = get_unaligned_le64(queries);
prod_info_addr++;
}
if (has_build_id_query) {
ret = rmi_read_block(rmi_dev, prod_info_addr, queries,
@ -241,13 +254,90 @@ static int rmi_f01_read_properties(struct rmi_device *rmi_dev,
return 0;
}
char *rmi_f01_get_product_ID(struct rmi_function *fn)
const char *rmi_f01_get_product_ID(struct rmi_function *fn)
{
struct f01_data *f01 = dev_get_drvdata(&fn->dev);
return f01->properties.product_id;
}
static ssize_t rmi_driver_manufacturer_id_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%d\n",
f01->properties.manufacturer_id);
}
static DEVICE_ATTR(manufacturer_id, 0444,
rmi_driver_manufacturer_id_show, NULL);
static ssize_t rmi_driver_dom_show(struct device *dev,
struct device_attribute *dattr, char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.dom);
}
static DEVICE_ATTR(date_of_manufacture, 0444, rmi_driver_dom_show, NULL);
static ssize_t rmi_driver_product_id_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%s\n", f01->properties.product_id);
}
static DEVICE_ATTR(product_id, 0444, rmi_driver_product_id_show, NULL);
static ssize_t rmi_driver_firmware_id_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
return scnprintf(buf, PAGE_SIZE, "%d\n", f01->properties.firmware_id);
}
static DEVICE_ATTR(firmware_id, 0444, rmi_driver_firmware_id_show, NULL);
static ssize_t rmi_driver_package_id_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct f01_data *f01 = dev_get_drvdata(&data->f01_container->dev);
u32 package_id = f01->properties.package_id;
return scnprintf(buf, PAGE_SIZE, "%04x.%04x\n",
package_id & 0xffff, (package_id >> 16) & 0xffff);
}
static DEVICE_ATTR(package_id, 0444, rmi_driver_package_id_show, NULL);
static struct attribute *rmi_f01_attrs[] = {
&dev_attr_manufacturer_id.attr,
&dev_attr_date_of_manufacture.attr,
&dev_attr_product_id.attr,
&dev_attr_firmware_id.attr,
&dev_attr_package_id.attr,
NULL
};
static struct attribute_group rmi_f01_attr_group = {
.attrs = rmi_f01_attrs,
};
#ifdef CONFIG_OF
static int rmi_f01_of_probe(struct device *dev,
struct rmi_device_platform_data *pdata)
@ -480,9 +570,18 @@ static int rmi_f01_probe(struct rmi_function *fn)
dev_set_drvdata(&fn->dev, f01);
error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
if (error)
dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error);
return 0;
}
static void rmi_f01_remove(struct rmi_function *fn)
{
sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
}
static int rmi_f01_config(struct rmi_function *fn)
{
struct f01_data *f01 = dev_get_drvdata(&fn->dev);
@ -622,6 +721,7 @@ struct rmi_function_handler rmi_f01_handler = {
},
.func = 0x01,
.probe = rmi_f01_probe,
.remove = rmi_f01_remove,
.config = rmi_f01_config,
.attention = rmi_f01_attention,
.suspend = rmi_f01_suspend,

Просмотреть файл

@ -26,15 +26,53 @@
#define RMI_F03_BYTES_PER_DEVICE_SHIFT 4
#define RMI_F03_QUEUE_LENGTH 0x0F
#define PSMOUSE_OOB_EXTRA_BTNS 0x01
struct f03_data {
struct rmi_function *fn;
struct serio *serio;
unsigned int overwrite_buttons;
u8 device_count;
u8 rx_queue_length;
};
int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
int value)
{
struct f03_data *f03 = dev_get_drvdata(&fn->dev);
unsigned int bit;
if (button < BTN_LEFT || button > BTN_MIDDLE)
return -EINVAL;
bit = BIT(button - BTN_LEFT);
if (value)
f03->overwrite_buttons |= bit;
else
f03->overwrite_buttons &= ~bit;
return 0;
}
void rmi_f03_commit_buttons(struct rmi_function *fn)
{
struct f03_data *f03 = dev_get_drvdata(&fn->dev);
struct serio *serio = f03->serio;
serio_pause_rx(serio);
if (serio->drv) {
serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
SERIO_OOB_DATA);
serio->drv->interrupt(serio, f03->overwrite_buttons,
SERIO_OOB_DATA);
}
serio_continue_rx(serio);
}
static int rmi_f03_pt_write(struct serio *id, unsigned char val)
{
struct f03_data *f03 = id->port_data;
@ -175,9 +213,6 @@ static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
int i;
int error;
if (!rmi_dev)
return -ENODEV;
if (drvdata->attn_data.data) {
/* First grab the data passed by the transport device */
if (drvdata->attn_data.size < ob_len) {

Просмотреть файл

@ -16,30 +16,24 @@
/* Defs for Query 0 */
#define RMI_F30_EXTENDED_PATTERNS 0x01
#define RMI_F30_HAS_MAPPABLE_BUTTONS (1 << 1)
#define RMI_F30_HAS_LED (1 << 2)
#define RMI_F30_HAS_GPIO (1 << 3)
#define RMI_F30_HAS_HAPTIC (1 << 4)
#define RMI_F30_HAS_GPIO_DRV_CTL (1 << 5)
#define RMI_F30_HAS_MECH_MOUSE_BTNS (1 << 6)
#define RMI_F30_HAS_MAPPABLE_BUTTONS BIT(1)
#define RMI_F30_HAS_LED BIT(2)
#define RMI_F30_HAS_GPIO BIT(3)
#define RMI_F30_HAS_HAPTIC BIT(4)
#define RMI_F30_HAS_GPIO_DRV_CTL BIT(5)
#define RMI_F30_HAS_MECH_MOUSE_BTNS BIT(6)
/* Defs for Query 1 */
#define RMI_F30_GPIO_LED_COUNT 0x1F
/* Defs for Control Registers */
#define RMI_F30_CTRL_1_GPIO_DEBOUNCE 0x01
#define RMI_F30_CTRL_1_HALT (1 << 4)
#define RMI_F30_CTRL_1_HALTED (1 << 5)
#define RMI_F30_CTRL_1_HALT BIT(4)
#define RMI_F30_CTRL_1_HALTED BIT(5)
#define RMI_F30_CTRL_10_NUM_MECH_MOUSE_BTNS 0x03
struct rmi_f30_ctrl_data {
int address;
int length;
u8 *regs;
};
#define RMI_F30_CTRL_MAX_REGS 32
#define RMI_F30_CTRL_MAX_BYTES ((RMI_F30_CTRL_MAX_REGS + 7) >> 3)
#define RMI_F30_CTRL_MAX_BYTES DIV_ROUND_UP(RMI_F30_CTRL_MAX_REGS, 8)
#define RMI_F30_CTRL_MAX_REG_BLOCKS 11
#define RMI_F30_CTRL_REGS_MAX_SIZE (RMI_F30_CTRL_MAX_BYTES \
@ -54,6 +48,15 @@ struct rmi_f30_ctrl_data {
+ 1 \
+ 1)
#define TRACKSTICK_RANGE_START 3
#define TRACKSTICK_RANGE_END 6
struct rmi_f30_ctrl_data {
int address;
int length;
u8 *regs;
};
struct f30_data {
/* Query Data */
bool has_extended_pattern;
@ -76,18 +79,21 @@ struct f30_data {
u16 *gpioled_key_map;
struct input_dev *input;
struct rmi_function *f03;
bool trackstick_buttons;
};
static int rmi_f30_read_control_parameters(struct rmi_function *fn,
struct f30_data *f30)
{
struct rmi_device *rmi_dev = fn->rmi_dev;
int error = 0;
int error;
error = rmi_read_block(rmi_dev, fn->fd.control_base_addr,
error = rmi_read_block(fn->rmi_dev, fn->fd.control_base_addr,
f30->ctrl_regs, f30->ctrl_regs_size);
if (error) {
dev_err(&rmi_dev->dev, "%s : Could not read control registers at 0x%x error (%d)\n",
dev_err(&fn->dev,
"%s: Could not read control registers at 0x%x: %d\n",
__func__, fn->fd.control_base_addr, error);
return error;
}
@ -95,24 +101,39 @@ static int rmi_f30_read_control_parameters(struct rmi_function *fn,
return 0;
}
static void rmi_f30_report_button(struct rmi_function *fn,
struct f30_data *f30, unsigned int button)
{
unsigned int reg_num = button >> 3;
unsigned int bit_num = button & 0x07;
u16 key_code = f30->gpioled_key_map[button];
bool key_down = !(f30->data_regs[reg_num] & BIT(bit_num));
if (f30->trackstick_buttons &&
button >= TRACKSTICK_RANGE_START &&
button <= TRACKSTICK_RANGE_END) {
rmi_f03_overwrite_button(f30->f03, key_code, key_down);
} else {
rmi_dbg(RMI_DEBUG_FN, &fn->dev,
"%s: call input report key (0x%04x) value (0x%02x)",
__func__, key_code, key_down);
input_report_key(f30->input, key_code, key_down);
}
}
static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
{
struct f30_data *f30 = dev_get_drvdata(&fn->dev);
struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
int retval;
int gpiled = 0;
int value = 0;
struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
int error;
int i;
int reg_num;
if (!f30->input)
return 0;
/* Read the gpi led data. */
if (drvdata->attn_data.data) {
if (drvdata->attn_data.size < f30->register_count) {
dev_warn(&fn->dev, "F30 interrupted, but data is missing\n");
dev_warn(&fn->dev,
"F30 interrupted, but data is missing\n");
return 0;
}
memcpy(f30->data_regs, drvdata->attn_data.data,
@ -120,72 +141,24 @@ static int rmi_f30_attention(struct rmi_function *fn, unsigned long *irq_bits)
drvdata->attn_data.data += f30->register_count;
drvdata->attn_data.size -= f30->register_count;
} else {
retval = rmi_read_block(rmi_dev, fn->fd.data_base_addr,
error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
f30->data_regs, f30->register_count);
if (retval) {
dev_err(&fn->dev, "%s: Failed to read F30 data registers.\n",
__func__);
return retval;
if (error) {
dev_err(&fn->dev,
"%s: Failed to read F30 data registers: %d\n",
__func__, error);
return error;
}
}
for (reg_num = 0; reg_num < f30->register_count; ++reg_num) {
for (i = 0; gpiled < f30->gpioled_count && i < 8; ++i,
++gpiled) {
if (f30->gpioled_key_map[gpiled] != 0) {
/* buttons have pull up resistors */
value = (((f30->data_regs[reg_num] >> i) & 0x01)
== 0);
rmi_dbg(RMI_DEBUG_FN, &fn->dev,
"%s: call input report key (0x%04x) value (0x%02x)",
__func__,
f30->gpioled_key_map[gpiled], value);
input_report_key(f30->input,
f30->gpioled_key_map[gpiled],
value);
if (f30->has_gpio) {
for (i = 0; i < f30->gpioled_count; i++)
if (f30->gpioled_key_map[i] != KEY_RESERVED)
rmi_f30_report_button(fn, f30, i);
if (f30->trackstick_buttons)
rmi_f03_commit_buttons(f30->f03);
}
}
}
return 0;
}
static int rmi_f30_register_device(struct rmi_function *fn)
{
int i;
struct rmi_device *rmi_dev = fn->rmi_dev;
struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
struct f30_data *f30 = dev_get_drvdata(&fn->dev);
struct input_dev *input_dev;
int button_count = 0;
input_dev = drv_data->input;
if (!input_dev) {
dev_info(&fn->dev, "F30: no input device found, ignoring.\n");
return -EINVAL;
}
f30->input = input_dev;
set_bit(EV_KEY, input_dev->evbit);
input_dev->keycode = f30->gpioled_key_map;
input_dev->keycodesize = sizeof(u16);
input_dev->keycodemax = f30->gpioled_count;
for (i = 0; i < f30->gpioled_count; i++) {
if (f30->gpioled_key_map[i] != 0) {
input_set_capability(input_dev, EV_KEY,
f30->gpioled_key_map[i]);
button_count++;
}
}
if (button_count == 1)
__set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit);
return 0;
}
@ -197,6 +170,12 @@ static int rmi_f30_config(struct rmi_function *fn)
rmi_get_platform_data(fn->rmi_dev);
int error;
if (pdata->f30_data.trackstick_buttons) {
/* Try [re-]establish link to F03. */
f30->f03 = rmi_find_function(fn->rmi_dev, 0x03);
f30->trackstick_buttons = f30->f03 != NULL;
}
if (pdata->f30_data.disable) {
drv->clear_irq_bits(fn->rmi_dev, fn->irq_mask);
} else {
@ -204,18 +183,19 @@ static int rmi_f30_config(struct rmi_function *fn)
error = rmi_write_block(fn->rmi_dev, fn->fd.control_base_addr,
f30->ctrl_regs, f30->ctrl_regs_size);
if (error) {
dev_err(&fn->rmi_dev->dev,
"%s : Could not write control registers at 0x%x error (%d)\n",
dev_err(&fn->dev,
"%s: Could not write control registers at 0x%x: %d\n",
__func__, fn->fd.control_base_addr, error);
return error;
}
drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);
}
return 0;
}
static inline void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
static void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
int *ctrl_addr, int len, u8 **reg)
{
ctrl->address = *ctrl_addr;
@ -225,8 +205,7 @@ static inline void rmi_f30_set_ctrl_data(struct rmi_f30_ctrl_data *ctrl,
*reg += len;
}
static inline bool rmi_f30_is_valid_button(int button,
struct rmi_f30_ctrl_data *ctrl)
static bool rmi_f30_is_valid_button(int button, struct rmi_f30_ctrl_data *ctrl)
{
int byte_position = button >> 3;
int bit_position = button & 0x07;
@ -239,32 +218,66 @@ static inline bool rmi_f30_is_valid_button(int button,
(ctrl[3].regs[byte_position] & BIT(bit_position));
}
static inline int rmi_f30_initialize(struct rmi_function *fn)
static int rmi_f30_map_gpios(struct rmi_function *fn,
struct f30_data *f30)
{
struct f30_data *f30;
struct rmi_device *rmi_dev = fn->rmi_dev;
const struct rmi_device_platform_data *pdata;
int retval = 0;
int control_address;
const struct rmi_device_platform_data *pdata =
rmi_get_platform_data(fn->rmi_dev);
struct input_dev *input = f30->input;
unsigned int button = BTN_LEFT;
unsigned int trackstick_button = BTN_LEFT;
bool button_mapped = false;
int i;
int button;
u8 buf[RMI_F30_QUERY_SIZE];
u8 *ctrl_reg;
u8 *map_memory;
f30 = devm_kzalloc(&fn->dev, sizeof(struct f30_data),
f30->gpioled_key_map = devm_kcalloc(&fn->dev,
f30->gpioled_count,
sizeof(f30->gpioled_key_map[0]),
GFP_KERNEL);
if (!f30)
if (!f30->gpioled_key_map) {
dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n");
return -ENOMEM;
}
dev_set_drvdata(&fn->dev, f30);
for (i = 0; i < f30->gpioled_count; i++) {
if (!rmi_f30_is_valid_button(i, f30->ctrl))
continue;
retval = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr, buf,
RMI_F30_QUERY_SIZE);
if (pdata->f30_data.trackstick_buttons &&
i >= TRACKSTICK_RANGE_START && i < TRACKSTICK_RANGE_END) {
f30->gpioled_key_map[i] = trackstick_button++;
} else if (!pdata->f30_data.buttonpad || !button_mapped) {
f30->gpioled_key_map[i] = button;
input_set_capability(input, EV_KEY, button++);
button_mapped = true;
}
}
if (retval) {
dev_err(&fn->dev, "Failed to read query register.\n");
return retval;
input->keycode = f30->gpioled_key_map;
input->keycodesize = sizeof(f30->gpioled_key_map[0]);
input->keycodemax = f30->gpioled_count;
/*
* Buttonpad could be also inferred from f30->has_mech_mouse_btns,
* but I am not sure, so use only the pdata info.
*/
if (pdata->f30_data.buttonpad)
__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
return 0;
}
static int rmi_f30_initialize(struct rmi_function *fn, struct f30_data *f30)
{
u8 *ctrl_reg = f30->ctrl_regs;
int control_address = fn->fd.control_base_addr;
u8 buf[RMI_F30_QUERY_SIZE];
int error;
error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr,
buf, RMI_F30_QUERY_SIZE);
if (error) {
dev_err(&fn->dev, "Failed to read query register\n");
return error;
}
f30->has_extended_pattern = buf[0] & RMI_F30_EXTENDED_PATTERNS;
@ -276,17 +289,14 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
f30->has_mech_mouse_btns = buf[0] & RMI_F30_HAS_MECH_MOUSE_BTNS;
f30->gpioled_count = buf[1] & RMI_F30_GPIO_LED_COUNT;
f30->register_count = (f30->gpioled_count + 7) >> 3;
control_address = fn->fd.control_base_addr;
ctrl_reg = f30->ctrl_regs;
f30->register_count = DIV_ROUND_UP(f30->gpioled_count, 8);
if (f30->has_gpio && f30->has_led)
rmi_f30_set_ctrl_data(&f30->ctrl[0], &control_address,
f30->register_count, &ctrl_reg);
rmi_f30_set_ctrl_data(&f30->ctrl[1], &control_address, sizeof(u8),
&ctrl_reg);
rmi_f30_set_ctrl_data(&f30->ctrl[1], &control_address,
sizeof(u8), &ctrl_reg);
if (f30->has_gpio) {
rmi_f30_set_ctrl_data(&f30->ctrl[2], &control_address,
@ -297,18 +307,12 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
}
if (f30->has_led) {
int ctrl5_len;
rmi_f30_set_ctrl_data(&f30->ctrl[4], &control_address,
f30->register_count, &ctrl_reg);
if (f30->has_extended_pattern)
ctrl5_len = 6;
else
ctrl5_len = 2;
rmi_f30_set_ctrl_data(&f30->ctrl[5], &control_address,
ctrl5_len, &ctrl_reg);
f30->has_extended_pattern ? 6 : 2,
&ctrl_reg);
}
if (f30->has_led || f30->has_gpio_driver_control) {
@ -335,42 +339,21 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
rmi_f30_set_ctrl_data(&f30->ctrl[10], &control_address,
sizeof(u8), &ctrl_reg);
f30->ctrl_regs_size = ctrl_reg - f30->ctrl_regs
?: RMI_F30_CTRL_REGS_MAX_SIZE;
f30->ctrl_regs_size = ctrl_reg -
f30->ctrl_regs ?: RMI_F30_CTRL_REGS_MAX_SIZE;
retval = rmi_f30_read_control_parameters(fn, f30);
if (retval < 0) {
error = rmi_f30_read_control_parameters(fn, f30);
if (error) {
dev_err(&fn->dev,
"Failed to initialize F19 control params.\n");
return retval;
"Failed to initialize F30 control params: %d\n",
error);
return error;
}
map_memory = devm_kzalloc(&fn->dev,
(f30->gpioled_count * (sizeof(u16))),
GFP_KERNEL);
if (!map_memory) {
dev_err(&fn->dev, "Failed to allocate gpioled map memory.\n");
return -ENOMEM;
}
f30->gpioled_key_map = (u16 *)map_memory;
pdata = rmi_get_platform_data(rmi_dev);
if (f30->has_gpio) {
button = BTN_LEFT;
for (i = 0; i < f30->gpioled_count; i++) {
if (rmi_f30_is_valid_button(i, f30->ctrl)) {
f30->gpioled_key_map[i] = button++;
/*
* buttonpad might be given by
* f30->has_mech_mouse_btns, but I am
* not sure, so use only the pdata info
*/
if (pdata->f30_data.buttonpad)
break;
}
}
error = rmi_f30_map_gpios(fn, f30);
if (error)
return error;
}
return 0;
@ -378,26 +361,33 @@ static inline int rmi_f30_initialize(struct rmi_function *fn)
static int rmi_f30_probe(struct rmi_function *fn)
{
int rc;
struct rmi_device *rmi_dev = fn->rmi_dev;
const struct rmi_device_platform_data *pdata =
rmi_get_platform_data(fn->rmi_dev);
rmi_get_platform_data(rmi_dev);
struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
struct f30_data *f30;
int error;
if (pdata->f30_data.disable)
return 0;
rc = rmi_f30_initialize(fn);
if (rc < 0)
goto error_exit;
if (!drv_data->input) {
dev_info(&fn->dev, "F30: no input device found, ignoring\n");
return -ENXIO;
}
rc = rmi_f30_register_device(fn);
if (rc < 0)
goto error_exit;
f30 = devm_kzalloc(&fn->dev, sizeof(*f30), GFP_KERNEL);
if (!f30)
return -ENOMEM;
f30->input = drv_data->input;
error = rmi_f30_initialize(fn, f30);
if (error)
return error;
dev_set_drvdata(&fn->dev, f30);
return 0;
error_exit:
return rc;
}
struct rmi_function_handler rmi_f30_handler = {

Просмотреть файл

@ -157,6 +157,9 @@ static int rmi_f34_write_blocks(struct f34_data *f34, const void *data,
i + 1, block_count);
data += f34->v5.block_size;
f34->update_progress += f34->v5.block_size;
f34->update_status = (f34->update_progress * 100) /
f34->update_size;
}
return 0;
@ -174,7 +177,7 @@ static int rmi_f34_write_config(struct f34_data *f34, const void *data)
F34_WRITE_CONFIG_BLOCK);
}
int rmi_f34_enable_flash(struct f34_data *f34)
static int rmi_f34_enable_flash(struct f34_data *f34)
{
return rmi_f34_command(f34, F34_ENABLE_FLASH_PROG,
F34_ENABLE_WAIT_MS, true);
@ -184,9 +187,14 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
const struct rmi_f34_firmware *syn_fw)
{
struct rmi_function *fn = f34->fn;
u32 image_size = le32_to_cpu(syn_fw->image_size);
u32 config_size = le32_to_cpu(syn_fw->config_size);
int ret;
if (syn_fw->image_size) {
f34->update_progress = 0;
f34->update_size = image_size + config_size;
if (image_size) {
dev_info(&fn->dev, "Erasing firmware...\n");
ret = rmi_f34_command(f34, F34_ERASE_ALL,
F34_ERASE_WAIT_MS, true);
@ -194,18 +202,18 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
return ret;
dev_info(&fn->dev, "Writing firmware (%d bytes)...\n",
syn_fw->image_size);
image_size);
ret = rmi_f34_write_firmware(f34, syn_fw->data);
if (ret)
return ret;
}
if (syn_fw->config_size) {
if (config_size) {
/*
* We only need to erase config if we haven't updated
* firmware.
*/
if (!syn_fw->image_size) {
if (!image_size) {
dev_info(&fn->dev, "Erasing config...\n");
ret = rmi_f34_command(f34, F34_ERASE_CONFIG,
F34_ERASE_WAIT_MS, true);
@ -214,9 +222,8 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
}
dev_info(&fn->dev, "Writing config (%d bytes)...\n",
syn_fw->config_size);
ret = rmi_f34_write_config(f34,
&syn_fw->data[syn_fw->image_size]);
config_size);
ret = rmi_f34_write_config(f34, &syn_fw->data[image_size]);
if (ret)
return ret;
}
@ -224,21 +231,23 @@ static int rmi_f34_flash_firmware(struct f34_data *f34,
return 0;
}
int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
static int rmi_f34_update_firmware(struct f34_data *f34,
const struct firmware *fw)
{
const struct rmi_f34_firmware *syn_fw;
const struct rmi_f34_firmware *syn_fw =
(const struct rmi_f34_firmware *)fw->data;
u32 image_size = le32_to_cpu(syn_fw->image_size);
u32 config_size = le32_to_cpu(syn_fw->config_size);
int ret;
syn_fw = (const struct rmi_f34_firmware *)fw->data;
BUILD_BUG_ON(offsetof(struct rmi_f34_firmware, data) !=
F34_FW_IMAGE_OFFSET);
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
"FW size:%d, checksum:%08x, image_size:%d, config_size:%d\n",
(int)fw->size,
"FW size:%zd, checksum:%08x, image_size:%d, config_size:%d\n",
fw->size,
le32_to_cpu(syn_fw->checksum),
le32_to_cpu(syn_fw->image_size),
le32_to_cpu(syn_fw->config_size));
image_size, config_size);
rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
"FW bootloader_id:%02x, product_id:%.*s, info: %02x%02x\n",
@ -246,27 +255,25 @@ int rmi_f34_update_firmware(struct f34_data *f34, const struct firmware *fw)
(int)sizeof(syn_fw->product_id), syn_fw->product_id,
syn_fw->product_info[0], syn_fw->product_info[1]);
if (syn_fw->image_size &&
syn_fw->image_size != f34->v5.fw_blocks * f34->v5.block_size) {
if (image_size && image_size != f34->v5.fw_blocks * f34->v5.block_size) {
dev_err(&f34->fn->dev,
"Bad firmware image: fw size %d, expected %d\n",
syn_fw->image_size,
f34->v5.fw_blocks * f34->v5.block_size);
image_size, f34->v5.fw_blocks * f34->v5.block_size);
ret = -EILSEQ;
goto out;
}
if (syn_fw->config_size &&
syn_fw->config_size != f34->v5.config_blocks * f34->v5.block_size) {
if (config_size &&
config_size != f34->v5.config_blocks * f34->v5.block_size) {
dev_err(&f34->fn->dev,
"Bad firmware image: config size %d, expected %d\n",
syn_fw->config_size,
config_size,
f34->v5.config_blocks * f34->v5.block_size);
ret = -EILSEQ;
goto out;
}
if (syn_fw->image_size && !syn_fw->config_size) {
if (image_size && !config_size) {
dev_err(&f34->fn->dev, "Bad firmware image: no config data\n");
ret = -EILSEQ;
goto out;
@ -283,6 +290,63 @@ out:
return ret;
}
static int rmi_f34_status(struct rmi_function *fn)
{
struct f34_data *f34 = dev_get_drvdata(&fn->dev);
/*
* The status is the percentage complete, or once complete,
* zero for success or a negative return code.
*/
return f34->update_status;
}
static ssize_t rmi_driver_bootloader_id_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct rmi_function *fn = data->f34_container;
struct f34_data *f34;
if (fn) {
f34 = dev_get_drvdata(&fn->dev);
if (f34->bl_version == 5)
return scnprintf(buf, PAGE_SIZE, "%c%c\n",
f34->bootloader_id[0],
f34->bootloader_id[1]);
else
return scnprintf(buf, PAGE_SIZE, "V%d.%d\n",
f34->bootloader_id[1],
f34->bootloader_id[0]);
}
return 0;
}
static DEVICE_ATTR(bootloader_id, 0444, rmi_driver_bootloader_id_show, NULL);
static ssize_t rmi_driver_configuration_id_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
struct rmi_function *fn = data->f34_container;
struct f34_data *f34;
if (fn) {
f34 = dev_get_drvdata(&fn->dev);
return scnprintf(buf, PAGE_SIZE, "%s\n", f34->configuration_id);
}
return 0;
}
static DEVICE_ATTR(configuration_id, 0444,
rmi_driver_configuration_id_show, NULL);
static int rmi_firmware_update(struct rmi_driver_data *data,
const struct firmware *fw)
{
@ -346,7 +410,13 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
else
ret = rmi_f34_update_firmware(f34, fw);
dev_info(&f34->fn->dev, "Firmware update complete, status:%d\n", ret);
if (ret) {
f34->update_status = ret;
dev_err(&f34->fn->dev,
"Firmware update failed, status: %d\n", ret);
} else {
dev_info(&f34->fn->dev, "Firmware update complete\n");
}
rmi_disable_irq(rmi_dev, false);
@ -377,9 +447,6 @@ static int rmi_firmware_update(struct rmi_driver_data *data,
return ret;
}
static int rmi_firmware_update(struct rmi_driver_data *data,
const struct firmware *fw);
static ssize_t rmi_driver_update_fw_store(struct device *dev,
struct device_attribute *dattr,
const char *buf, size_t count)
@ -414,8 +481,27 @@ static ssize_t rmi_driver_update_fw_store(struct device *dev,
static DEVICE_ATTR(update_fw, 0200, NULL, rmi_driver_update_fw_store);
static ssize_t rmi_driver_update_fw_status_show(struct device *dev,
struct device_attribute *dattr,
char *buf)
{
struct rmi_driver_data *data = dev_get_drvdata(dev);
int update_status = 0;
if (data->f34_container)
update_status = rmi_f34_status(data->f34_container);
return scnprintf(buf, PAGE_SIZE, "%d\n", update_status);
}
static DEVICE_ATTR(update_fw_status, 0444,
rmi_driver_update_fw_status_show, NULL);
static struct attribute *rmi_firmware_attrs[] = {
&dev_attr_bootloader_id.attr,
&dev_attr_configuration_id.attr,
&dev_attr_update_fw.attr,
&dev_attr_update_fw_status.attr,
NULL
};
@ -441,8 +527,6 @@ static int rmi_f34_probe(struct rmi_function *fn)
/* v5 code only supported version 0, try V7 probe */
if (version > 0)
return rmi_f34v7_probe(f34);
else if (version != 0)
return -ENODEV;
f34->bl_version = 5;

Просмотреть файл

@ -301,6 +301,10 @@ struct f34_data {
unsigned char bootloader_id[5];
unsigned char configuration_id[CONFIG_ID_SIZE*2 + 1];
int update_status;
int update_progress;
int update_size;
union {
struct f34v5_data v5;
struct f34v7_data v7;

Просмотреть файл

@ -588,6 +588,7 @@ static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34)
u16 block_count;
block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
f34->update_size += block_count;
if (block_count != f34->v7.blkcount.ui_firmware) {
dev_err(&f34->fn->dev,
@ -604,6 +605,7 @@ static int rmi_f34v7_check_ui_config_size(struct f34_data *f34)
u16 block_count;
block_count = f34->v7.img.ui_config.size / f34->v7.block_size;
f34->update_size += block_count;
if (block_count != f34->v7.blkcount.ui_config) {
dev_err(&f34->fn->dev, "UI config size mismatch\n");
@ -618,6 +620,7 @@ static int rmi_f34v7_check_dp_config_size(struct f34_data *f34)
u16 block_count;
block_count = f34->v7.img.dp_config.size / f34->v7.block_size;
f34->update_size += block_count;
if (block_count != f34->v7.blkcount.dp_config) {
dev_err(&f34->fn->dev, "Display config size mismatch\n");
@ -632,6 +635,8 @@ static int rmi_f34v7_check_guest_code_size(struct f34_data *f34)
u16 block_count;
block_count = f34->v7.img.guest_code.size / f34->v7.block_size;
f34->update_size += block_count;
if (block_count != f34->v7.blkcount.guest_code) {
dev_err(&f34->fn->dev, "Guest code size mismatch\n");
return -EINVAL;
@ -645,6 +650,7 @@ static int rmi_f34v7_check_bl_config_size(struct f34_data *f34)
u16 block_count;
block_count = f34->v7.img.bl_config.size / f34->v7.block_size;
f34->update_size += block_count;
if (block_count != f34->v7.blkcount.bl_config) {
dev_err(&f34->fn->dev, "Bootloader config size mismatch\n");
@ -881,6 +887,9 @@ static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
block_ptr += (transfer * f34->v7.block_size);
remaining -= transfer;
f34->update_progress += transfer;
f34->update_status = (f34->update_progress * 100) /
f34->update_size;
} while (remaining);
return 0;
@ -1191,6 +1200,8 @@ int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
rmi_f34v7_read_queries_bl_version(f34);
f34->v7.image = fw->data;
f34->update_progress = 0;
f34->update_size = 0;
ret = rmi_f34v7_parse_image_info(f34);
if (ret < 0)

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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);

Просмотреть файл

@ -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)

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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
@ -1177,6 +1165,17 @@ config TOUCHSCREEN_TPS6507X
To compile this driver as a module, choose M here: the
module will be called tps6507x_ts.
config TOUCHSCREEN_ZET6223
tristate "Zeitec ZET6223 touchscreen driver"
depends on I2C
help
Say Y here if you have a touchscreen using Zeitec ZET6223
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called zet6223.
config TOUCHSCREEN_ZFORCE
tristate "Neonode zForce infrared touchscreens"
depends on I2C

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше