Commit 9f7a9b11 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull input updates from Dmitry Torokhov:

 - three new touchscreen drivers: EETI EXC3000, HiDeep, and Samsung
   S6SY761

 - the timer API conversion (setup_timer() -> timer_setup())

 - a few drivers swiytched to using managed API for creating custom
   device attributes

 - other assorted fixed and cleanups.

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (50 commits)
  Input: gamecon - mark expected switch fall-throughs
  Input: sidewinder - mark expected switch fall-throughs
  Input: spaceball - mark expected switch fall-throughs
  Input: uinput - unlock on allocation failure in ioctl
  Input: add support for the Samsung S6SY761 touchscreen
  Input: add support for HiDeep touchscreen
  Input: st1232 - remove obsolete platform device support
  Input: convert autorepeat timer to use timer_setup()
  media: ttpci: remove autorepeat handling and use timer_setup
  Input: cyttsp4 - avoid overflows when calculating memory sizes
  Input: mxs-lradc - remove redundant assignment to pointer input
  Input: add I2C attached EETI EXC3000 multi touch driver
  Input: goodix - support gt1151 touchpanel
  Input: ps2-gpio - actually abort probe when connected to sleeping GPIOs
  Input: hil_mlc - convert to using timer_setup()
  Input: hp_sdc - convert to using timer_setup()
  Input: touchsceen - convert timers to use timer_setup()
  Input: keyboard - convert timers to use timer_setup()
  Input: uinput - fold header into the driver proper
  Input: uinput - remove uinput_allocate_device()
  ...
parents 4e4510fe c2514106
Device-Tree bindings for GPIO attached mice
This simply uses standard GPIO handles to define a simple mouse connected
to 5-7 GPIO lines.
Required properties:
- compatible: must be "gpio-mouse"
- scan-interval-ms: The scanning interval in milliseconds
- up-gpios: GPIO line phandle to the line indicating "up"
- down-gpios: GPIO line phandle to the line indicating "down"
- left-gpios: GPIO line phandle to the line indicating "left"
- right-gpios: GPIO line phandle to the line indicating "right"
Optional properties:
- button-left-gpios: GPIO line handle to the left mouse button
- button-middle-gpios: GPIO line handle to the middle mouse button
- button-right-gpios: GPIO line handle to the right mouse button
Example:
#include <dt-bindings/gpio/gpio.h>
gpio-mouse {
compatible = "gpio-mouse";
scan-interval-ms = <50>;
up-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>;
down-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
left-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
right-gpios = <&gpio0 3 GPIO_ACTIVE_LOW>;
button-left-gpios = <&gpio0 4 GPIO_ACTIVE_LOW>;
button-middle-gpios = <&gpio0 5 GPIO_ACTIVE_LOW>;
button-right-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
};
* EETI EXC3000 Multiple Touch Controller
Required properties:
- compatible: must be "eeti,exc3000"
- reg: i2c slave address
- interrupt-parent: the phandle for the interrupt controller
- interrupts: touch controller interrupt
- touchscreen-size-x: See touchscreen.txt
- touchscreen-size-y: See touchscreen.txt
Optional properties:
- touchscreen-inverted-x: See touchscreen.txt
- touchscreen-inverted-y: See touchscreen.txt
- touchscreen-swapped-x-y: See touchscreen.txt
Example:
touchscreen@2a {
compatible = "eeti,exc3000";
reg = <0x2a>;
interrupt-parent = <&gpio1>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
touchscreen-size-x = <4096>;
touchscreen-size-y = <4096>;
touchscreen-inverted-x;
touchscreen-swapped-x-y;
};
......@@ -2,7 +2,8 @@ Device tree bindings for Goodix GT9xx series touchscreen controller
Required properties:
- compatible : Should be "goodix,gt911"
- compatible : Should be "goodix,gt1151"
or "goodix,gt911"
or "goodix,gt9110"
or "goodix,gt912"
or "goodix,gt927"
......
* HiDeep Finger and Stylus touchscreen controller
Required properties:
- compatible : must be "hideep,hideep-ts"
- reg : I2C slave address, (e.g. 0x6C).
- interrupt-parent : Interrupt controller to which the chip is connected.
- interrupts : Interrupt to which the chip is connected.
Optional properties:
- vdd-supply : It is the controller supply for controlling
main voltage(3.3V) through the regulator.
- vid-supply : It is the controller supply for controlling
IO voltage(1.8V) through the regulator.
- reset-gpios : Define for reset gpio pin.
It is to use for reset IC.
- touchscreen-size-x : X axis size of touchscreen
- touchscreen-size-y : Y axis size of touchscreen
- linux,keycodes : Specifies an array of numeric keycode values to
be used for reporting button presses. The array can
contain up to 3 entries.
Example:
#include "dt-bindings/input/input.h"
i2c@00000000 {
/* ... */
touchscreen@6c {
compatible = "hideep,hideep-ts";
reg = <0x6c>;
interrupt-parent = <&gpx1>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&ldo15_reg>";
vid-supply = <&ldo18_reg>;
reset-gpios = <&gpx1 5 0>;
touchscreen-size-x = <1080>;
touchscreen-size-y = <1920>;
linux,keycodes = <KEY_HOME>, <KEY_MENU>, <KEY_BACK>;
};
};
* Samsung S6SY761 touchscreen controller
Required properties:
- compatible : must be "samsung,s6sy761"
- reg : I2C slave address, (e.g. 0x48)
- interrupt-parent : the phandle to the interrupt controller which provides
the interrupt
- interrupts : interrupt specification
- avdd-supply : analogic power supply
- vdd-supply : power supply
Optional properties:
- touchscreen-size-x : see touchscreen.txt. This property is embedded in the
device. If defined it forces a different x resolution.
- touchscreen-size-y : see touchscreen.txt. This property is embedded in the
device. If defined it forces a different y resolution.
Example:
i2c@00000000 {
/* ... */
touchscreen@48 {
compatible = "samsung,s6sy761";
reg = <0x48>;
interrupt-parent = <&gpa1>;
interrupts = <1 IRQ_TYPE_NONE>;
avdd-supply = <&ldo30_reg>;
vdd-supply = <&ldo31_reg>;
touchscreen-size-x = <4096>;
touchscreen-size-y = <4096>;
};
};
......@@ -137,6 +137,7 @@ gw Gateworks Corporation
hannstar HannStar Display Corporation
haoyu Haoyu Microelectronic Co. Ltd.
hardkernel Hardkernel Co., Ltd
hideep HiDeep Inc.
himax Himax Technologies, Inc.
hisilicon Hisilicon Limited.
hit Hitachi Ltd.
......
......@@ -412,10 +412,10 @@ static void ml_play_effects(struct ml_device *ml)
ml_schedule_timer(ml);
}
static void ml_effect_timer(unsigned long timer_data)
static void ml_effect_timer(struct timer_list *t)
{
struct input_dev *dev = (struct input_dev *)timer_data;
struct ml_device *ml = dev->ff->private;
struct ml_device *ml = from_timer(ml, t, timer);
struct input_dev *dev = ml->dev;
unsigned long flags;
pr_debug("timer: updating effects\n");
......@@ -526,7 +526,7 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
ml->private = data;
ml->play_effect = play_effect;
ml->gain = 0xffff;
setup_timer(&ml->timer, ml_effect_timer, (unsigned long)dev);
timer_setup(&ml->timer, ml_effect_timer, 0);
set_bit(FF_GAIN, dev->ffbit);
......
......@@ -76,7 +76,7 @@ static void input_start_autorepeat(struct input_dev *dev, int code)
{
if (test_bit(EV_REP, dev->evbit) &&
dev->rep[REP_PERIOD] && dev->rep[REP_DELAY] &&
dev->timer.data) {
dev->timer.function) {
dev->repeat_key = code;
mod_timer(&dev->timer,
jiffies + msecs_to_jiffies(dev->rep[REP_DELAY]));
......@@ -179,9 +179,9 @@ static void input_pass_event(struct input_dev *dev,
* dev->event_lock here to avoid racing with input_event
* which may cause keys get "stuck".
*/
static void input_repeat_key(unsigned long data)
static void input_repeat_key(struct timer_list *t)
{
struct input_dev *dev = (void *) data;
struct input_dev *dev = from_timer(dev, t, timer);
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
......@@ -1784,7 +1784,7 @@ struct input_dev *input_allocate_device(void)
device_initialize(&dev->dev);
mutex_init(&dev->mutex);
spin_lock_init(&dev->event_lock);
init_timer(&dev->timer);
timer_setup(&dev->timer, NULL, 0);
INIT_LIST_HEAD(&dev->h_list);
INIT_LIST_HEAD(&dev->node);
......@@ -2047,8 +2047,7 @@ static void devm_input_device_unregister(struct device *dev, void *res)
*/
void input_enable_softrepeat(struct input_dev *dev, int delay, int period)
{
dev->timer.data = (unsigned long) dev;
dev->timer.function = input_repeat_key;
dev->timer.function = (TIMER_FUNC_TYPE)input_repeat_key;
dev->rep[REP_DELAY] = delay;
dev->rep[REP_PERIOD] = period;
}
......
......@@ -654,6 +654,7 @@ static void gc_psx_report_one(struct gc_pad *pad, unsigned char psx_type,
input_report_key(dev, BTN_THUMBL, ~data[0] & 0x04);
input_report_key(dev, BTN_THUMBR, ~data[0] & 0x02);
/* fall through */
case GC_PSX_NEGCON:
case GC_PSX_ANALOG:
......@@ -887,6 +888,7 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type)
case GC_SNES:
for (i = 4; i < 8; i++)
__set_bit(gc_snes_btn[i], input_dev->keybit);
/* fall through */
case GC_NES:
for (i = 0; i < 4; i++)
__set_bit(gc_snes_btn[i], input_dev->keybit);
......@@ -894,6 +896,7 @@ static int gc_setup_pad(struct gc *gc, int idx, int pad_type)
case GC_MULTI2:
__set_bit(BTN_THUMB, input_dev->keybit);
/* fall through */
case GC_MULTI:
__set_bit(BTN_TRIGGER, input_dev->keybit);
break;
......
......@@ -672,16 +672,16 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
switch (i * m) {
case 60:
sw->number++;
sw->number++; /* fall through */
case 45: /* Ambiguous packet length */
if (j <= 40) { /* ID length less or eq 40 -> FSP */
case 43:
sw->type = SW_ID_FSP;
break;
}
sw->number++;
sw->number++; /* fall through */
case 30:
sw->number++;
sw->number++; /* fall through */
case 15:
sw->type = SW_ID_GP;
break;
......@@ -697,9 +697,9 @@ static int sw_connect(struct gameport *gameport, struct gameport_driver *drv)
sw->type = SW_ID_PP;
break;
case 66:
sw->bits = 3;
sw->bits = 3; /* fall through */
case 198:
sw->length = 22;
sw->length = 22; /* fall through */
case 64:
sw->type = SW_ID_3DP;
if (j == 160)
......
......@@ -162,6 +162,7 @@ static irqreturn_t spaceball_interrupt(struct serio *serio,
break;
}
spaceball->escape = 0;
/* fall through */
case 'M':
case 'Q':
case 'S':
......@@ -169,6 +170,7 @@ static irqreturn_t spaceball_interrupt(struct serio *serio,
spaceball->escape = 0;
data &= 0x1f;
}
/* fall through */
default:
if (spaceball->escape)
spaceball->escape = 0;
......@@ -234,11 +236,13 @@ static int spaceball_connect(struct serio *serio, struct serio_driver *drv)
input_dev->keybit[BIT_WORD(BTN_A)] |= BIT_MASK(BTN_A) |
BIT_MASK(BTN_B) | BIT_MASK(BTN_C) |
BIT_MASK(BTN_MODE);
/* fall through */
default:
input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_2) |
BIT_MASK(BTN_3) | BIT_MASK(BTN_4) |
BIT_MASK(BTN_5) | BIT_MASK(BTN_6) |
BIT_MASK(BTN_7) | BIT_MASK(BTN_8);
/* fall through */
case SPACEBALL_3003C:
input_dev->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_1) |
BIT_MASK(BTN_8);
......
......@@ -127,10 +127,9 @@ static inline void bfin_kpad_clear_irq(void)
bfin_write_KPAD_ROWCOL(0xFFFF);
}
static void bfin_kpad_timer(unsigned long data)
static void bfin_kpad_timer(struct timer_list *t)
{
struct platform_device *pdev = (struct platform_device *) data;
struct bf54x_kpad *bf54x_kpad = platform_get_drvdata(pdev);
struct bf54x_kpad *bf54x_kpad = from_timer(bf54x_kpad, t, timer);
if (bfin_kpad_get_keypressed(bf54x_kpad)) {
/* Try again later */
......@@ -298,7 +297,7 @@ static int bfin_kpad_probe(struct platform_device *pdev)
/* Init Keypad Key Up/Release test timer */
setup_timer(&bf54x_kpad->timer, bfin_kpad_timer, (unsigned long) pdev);
timer_setup(&bf54x_kpad->timer, bfin_kpad_timer, 0);
bfin_write_KPAD_PRESCALE(bfin_kpad_get_prescale(TIME_SCALE));
......
......@@ -419,9 +419,9 @@ static irqreturn_t gpio_keys_gpio_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void gpio_keys_irq_timer(unsigned long _data)
static void gpio_keys_irq_timer(struct timer_list *t)
{
struct gpio_button_data *bdata = (struct gpio_button_data *)_data;
struct gpio_button_data *bdata = from_timer(bdata, t, release_timer);
struct input_dev *input = bdata->input;
unsigned long flags;
......@@ -582,8 +582,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
}
bdata->release_delay = button->debounce_interval;
setup_timer(&bdata->release_timer,
gpio_keys_irq_timer, (unsigned long)bdata);
timer_setup(&bdata->release_timer, gpio_keys_irq_timer, 0);
isr = gpio_keys_irq_isr;
irqflags = 0;
......
......@@ -184,9 +184,9 @@ static void imx_keypad_fire_events(struct imx_keypad *keypad,
/*
* imx_keypad_check_for_events is the timer handler.
*/
static void imx_keypad_check_for_events(unsigned long data)
static void imx_keypad_check_for_events(struct timer_list *t)
{
struct imx_keypad *keypad = (struct imx_keypad *) data;
struct imx_keypad *keypad = from_timer(keypad, t, check_matrix_timer);
unsigned short matrix_volatile_state[MAX_MATRIX_KEY_COLS];
unsigned short reg_val;
bool state_changed, is_zero_matrix;
......@@ -456,8 +456,8 @@ static int imx_keypad_probe(struct platform_device *pdev)
keypad->irq = irq;
keypad->stable_count = 0;
setup_timer(&keypad->check_matrix_timer,
imx_keypad_check_for_events, (unsigned long) keypad);
timer_setup(&keypad->check_matrix_timer,
imx_keypad_check_for_events, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res);
......
......@@ -210,9 +210,9 @@ static irqreturn_t locomokbd_interrupt(int irq, void *dev_id)
/*
* LoCoMo timer checking for released keys
*/
static void locomokbd_timer_callback(unsigned long data)
static void locomokbd_timer_callback(struct timer_list *t)
{
struct locomokbd *locomokbd = (struct locomokbd *) data;
struct locomokbd *locomokbd = from_timer(locomokbd, t, timer);
locomokbd_scankeyboard(locomokbd);
}
......@@ -264,8 +264,7 @@ static int locomokbd_probe(struct locomo_dev *dev)
spin_lock_init(&locomokbd->lock);
setup_timer(&locomokbd->timer, locomokbd_timer_callback,
(unsigned long)locomokbd);
timer_setup(&locomokbd->timer, locomokbd_timer_callback, 0);
locomokbd->suspend_jiffies = jiffies;
......
......@@ -41,7 +41,7 @@
#undef NEW_BOARD_LEARNING_MODE
static void omap_kp_tasklet(unsigned long);
static void omap_kp_timer(unsigned long);
static void omap_kp_timer(struct timer_list *);
static unsigned char keypad_state[8];
static DEFINE_MUTEX(kp_enable_mutex);
......@@ -74,7 +74,7 @@ static irqreturn_t omap_kp_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void omap_kp_timer(unsigned long data)
static void omap_kp_timer(struct timer_list *unused)
{
tasklet_schedule(&kp_tasklet);
}
......@@ -233,7 +233,7 @@ static int omap_kp_probe(struct platform_device *pdev)
col_idx = 0;
row_idx = 0;
setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp);
timer_setup(&omap_kp->timer, omap_kp_timer, 0);
/* get the irq and init timer*/
kp_tasklet.data = (unsigned long) omap_kp;
......
......@@ -45,9 +45,9 @@ struct pwrkey_drv_data {
struct input_dev *input;
};
static void imx_imx_snvs_check_for_events(unsigned long data)
static void imx_imx_snvs_check_for_events(struct timer_list *t)
{
struct pwrkey_drv_data *pdata = (struct pwrkey_drv_data *) data;
struct pwrkey_drv_data *pdata = from_timer(pdata, t, check_timer);
struct input_dev *input = pdata->input;
u32 state;
......@@ -134,8 +134,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev)
/* clear the unexpected interrupt before driver ready */
regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO);
setup_timer(&pdata->check_timer,
imx_imx_snvs_check_for_events, (unsigned long) pdata);
timer_setup(&pdata->check_timer, imx_imx_snvs_check_for_events, 0);
input = devm_input_allocate_device(&pdev->dev);
if (!input) {
......
......@@ -251,9 +251,9 @@ static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable)
writel(val, kbc->mmio + KBC_CONTROL_0);
}
static void tegra_kbc_keypress_timer(unsigned long data)
static void tegra_kbc_keypress_timer(struct timer_list *t)
{
struct tegra_kbc *kbc = (struct tegra_kbc *)data;
struct tegra_kbc *kbc = from_timer(kbc, t, timer);
unsigned long flags;
u32 val;
unsigned int i;
......@@ -655,7 +655,7 @@ static int tegra_kbc_probe(struct platform_device *pdev)
return -ENOMEM;
}
setup_timer(&kbc->timer, tegra_kbc_keypress_timer, (unsigned long)kbc);
timer_setup(&kbc->timer, tegra_kbc_keypress_timer, 0);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
kbc->mmio = devm_ioremap_resource(&pdev->dev, res);
......
......@@ -796,7 +796,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
if (pdata->watermark) {
ac->int_mask |= WATERMARK;
if (!FIFO_MODE(pdata->fifo_mode))
if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS)
ac->pdata.fifo_mode |= FIFO_STREAM;
} else {
ac->int_mask |= DATA_READY;
......
......@@ -31,6 +31,7 @@
* 0.1 20/06/2002
* - first public version
*/
#include <uapi/linux/uinput.h>
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/slab.h>
......@@ -38,10 +39,47 @@
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uinput.h>
#include <linux/input/mt.h>
#include "../input-compat.h"
#define UINPUT_NAME "uinput"
#define UINPUT_BUFFER_SIZE 16
#define UINPUT_NUM_REQUESTS 16
enum uinput_state { UIST_NEW_DEVICE, UIST_SETUP_COMPLETE, UIST_CREATED };
struct uinput_request {
unsigned int id;
unsigned int code; /* UI_FF_UPLOAD, UI_FF_ERASE */
int retval;
struct completion done;
union {
unsigned int effect_id;
struct {
struct ff_effect *effect;
struct ff_effect *old;
} upload;
} u;
};
struct uinput_device {
struct input_dev *dev;
struct mutex mutex;
enum uinput_state state;
wait_queue_head_t waitq;
unsigned char ready;
unsigned char head;
unsigned char tail;
struct input_event buff[UINPUT_BUFFER_SIZE];
unsigned int ff_effects_max;
struct uinput_request *requests[UINPUT_NUM_REQUESTS];
wait_queue_head_t requests_waitq;
spinlock_t requests_lock;
};
static int uinput_dev_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
......@@ -149,7 +187,11 @@ static int uinput_request_submit(struct uinput_device *udev,
if (retval)
goto out;
wait_for_completion(&request->done);
if (!wait_for_completion_timeout(&request->done, 30 * HZ)) {
retval = -ETIMEDOUT;
goto out;
}
retval = request->retval;
out:
......@@ -320,6 +362,10 @@ static int uinput_create_device(struct uinput_device *udev)
dev->flush = uinput_dev_flush;
}
dev->event = uinput_dev_event;
input_set_drvdata(udev->dev, udev);
error = input_register_device(udev->dev);
if (error)
goto fail2;
......@@ -402,18 +448,6 @@ static int uinput_validate_absbits(struct input_dev *dev)
return 0;
}
static int uinput_allocate_device(struct uinput_device *udev)
{
udev->dev = input_allocate_device();
if (!udev->dev)
return -ENOMEM;
udev->dev->event = uinput_dev_event;
input_set_drvdata(udev->dev, udev);
return 0;
}
static int uinput_dev_setup(struct uinput_device *udev,
struct uinput_setup __user *arg)
{
......@@ -489,9 +523,9 @@ static int uinput_setup_device_legacy(struct uinput_device *udev,
return -EINVAL;
if (!udev->dev) {
retval = uinput_allocate_device(udev);
if (retval)
return retval;
udev->dev = input_allocate_device();
if (!udev->dev)
return -ENOMEM;
}
dev = udev->dev;
......@@ -822,162 +856,163 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
return retval;
if (!udev->dev) {
retval = uinput_allocate_device(udev);
if (retval)
udev->dev = input_allocate_device();
if (!udev->dev) {
retval = -ENOMEM;
goto out;
}
}
switch (cmd) {
case UI_GET_VERSION:
if (put_user(UINPUT_VERSION,
(unsigned int __user *)p))
retval = -EFAULT;
goto out;
case UI_GET_VERSION:
if (put_user(UINPUT_VERSION, (unsigned int __user *)p))
retval = -EFAULT;
goto out;
case UI_DEV_CREATE:
retval = uinput_create_device(udev);
goto out;
case UI_DEV_CREATE:
retval = uinput_create_device(udev);
goto out;
case UI_DEV_DESTROY:
uinput_destroy_device(udev);
goto out;
case UI_DEV_DESTROY:
uinput_destroy_device(udev);
goto out;
case UI_DEV_SETUP:
retval = uinput_dev_setup(udev, p);
goto out;
case UI_DEV_SETUP:
retval = uinput_dev_setup(udev, p);
goto out;
/* UI_ABS_SETUP is handled in the variable size ioctls */
/* UI_ABS_SETUP is handled in the variable size ioctls */
case UI_SET_EVBIT:
retval = uinput_set_bit(arg, evbit, EV_MAX);
goto out;
case UI_SET_EVBIT:
retval = uinput_set_bit(arg, evbit, EV_MAX);
goto out;
case UI_SET_KEYBIT:
retval = uinput_set_bit(arg, keybit, KEY_MAX);
goto out;
case UI_SET_KEYBIT:
retval = uinput_set_bit(arg, keybit, KEY_MAX);
goto out;
case UI_SET_RELBIT:
retval = uinput_set_bit(arg, relbit, REL_MAX);
goto out;
case UI_SET_RELBIT:
retval = uinput_set_bit(arg, relbit, REL_MAX);
goto out;
case UI_SET_ABSBIT:
retval = uinput_set_bit(arg, absbit, ABS_MAX);
goto out;
case UI_SET_ABSBIT:
retval = uinput_set_bit(arg, absbit, ABS_MAX);
goto out;
case UI_SET_MSCBIT:
retval = uinput_set_bit(arg, mscbit, MSC_MAX);
goto out;
case UI_SET_MSCBIT:
retval = uinput_set_bit(arg, mscbit, MSC_MAX);
goto out;
case UI_SET_LEDBIT:
retval = uinput_set_bit(arg, ledbit, LED_MAX);
goto out;
case UI_SET_LEDBIT:
retval = uinput_set_bit(arg, ledbit, LED_MAX);
goto out;
case UI_SET_SNDBIT:
retval = uinput_set_bit(arg, sndbit, SND_MAX);
goto out;
case UI_SET_SNDBIT:
retval = uinput_set_bit(arg, sndbit, SND_MAX);
case UI_SET_FFBIT:
retval = uinput_set_bit(arg, ffbit, FF_MAX);
goto out;
case UI_SET_SWBIT:
retval = uinput_set_bit(arg, swbit, SW_MAX);
goto out;
case UI_SET_PROPBIT:
retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);
goto out;
case UI_SET_PHYS:
if (udev->state == UIST_CREATED) {
retval = -EINVAL;
goto out;
}
case UI_SET_FFBIT:
retval = uinput_set_bit(arg, ffbit, FF_MAX);
phys = strndup_user(p, 1024);
if (IS_ERR(phys)) {
retval = PTR_ERR(phys);
goto out;
}
kfree(udev->dev->phys);
udev->dev->phys = phys;
goto out;
case UI_SET_SWBIT:
retval = uinput_set_bit(arg, swbit, SW_MAX);
case UI_BEGIN_FF_UPLOAD:
retval = uinput_ff_upload_from_user(p, &ff_up);
if (retval)
goto out;
case UI_SET_PROPBIT:
retval = uinput_set_bit(arg, propbit, INPUT_PROP_MAX);
req = uinput_request_find(udev, ff_up.request_id);
if (!req || req->code != UI_FF_UPLOAD ||
!req->u.upload.effect) {
retval = -EINVAL;
goto out;
}
case UI_SET_PHYS:
if (udev->state == UIST_CREATED) {
retval = -EINVAL;
goto out;
}
ff_up.retval = 0;
ff_up.effect = *req->u.upload.effect;
if (req->u.upload.old)
ff_up.old = *req->u.upload.old;
else
memset(&ff_up.old, 0, sizeof(struct ff_effect));
phys = strndup_user(p, 1024);
if (IS_ERR(phys)) {
retval = PTR_ERR(phys);
goto out;
}
retval = uinput_ff_upload_to_user(p, &ff_up);
goto out;
kfree(udev->dev->phys);
udev->dev->phys = phys;
case UI_BEGIN_FF_ERASE:
if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
retval = -EFAULT;
goto out;
}
case UI_BEGIN_FF_UPLOAD:
retval = uinput_ff_upload_from_user(p, &ff_up);
if (retval)
goto out;
req = uinput_request_find(udev, ff_up.request_id);
if (!req || req->code != UI_FF_UPLOAD ||
!req->u.upload.effect) {
retval = -EINVAL;
goto out;
}
ff_up.retval = 0;
ff_up.effect = *req->u.upload.effect;
if (req->u.upload.old)
ff_up.old = *req->u.upload.old;
else
memset(&ff_up.old, 0, sizeof(struct ff_effect));
retval = uinput_ff_upload_to_user(p, &ff_up);
req = uinput_request_find(udev, ff_erase.request_id);
if (!req || req->code != UI_FF_ERASE) {
retval = -EINVAL;
goto out;
}
case UI_BEGIN_FF_ERASE:
if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
retval = -EFAULT;
goto out;
}
req = uinput_request_find(udev, ff_erase.request_id);
if (!req || req->code != UI_FF_ERASE) {
retval = -EINVAL;
goto out;
}
ff_erase.retval = 0;
ff_erase.effect_id = req->u.effect_id;
if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) {
retval = -EFAULT;
goto out;
}
ff_erase.retval = 0;
ff_erase.effect_id = req->u.effect_id;
if (copy_to_user(p, &ff_erase, sizeof(ff_erase))) {
retval = -EFAULT;
goto out;
}
case UI_END_FF_UPLOAD:
retval = uinput_ff_upload_from_user(p, &ff_up);
if (retval)
goto out;
goto out;
req = uinput_request_find(udev, ff_up.request_id);
if (!req || req->code != UI_FF_UPLOAD ||
!req->u.upload.effect) {
retval = -EINVAL;
goto out;
}
case UI_END_FF_UPLOAD:
retval = uinput_ff_upload_from_user(p, &ff_up);
if (retval)
goto out;
req->retval = ff_up.retval;
complete(&req->done);
req = uinput_request_find(udev, ff_up.request_id);
if (!req || req->code != UI_FF_UPLOAD ||
!req->u.upload.effect) {
retval = -EINVAL;
goto out;
}
case UI_END_FF_ERASE:
if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
retval = -EFAULT;
goto out;
}
req->retval = ff_up.retval;
complete(&req->done);
goto out;
req = uinput_request_find(udev, ff_erase.request_id);
if (!req || req->code != UI_FF_ERASE) {
retval = -EINVAL;
goto out;
}
case UI_END_FF_ERASE:
if (copy_from_user(&ff_erase, p, sizeof(ff_erase))) {
retval = -EFAULT;
goto out;
}
req->retval = ff_erase.retval;
complete(&req->done);
req = uinput_request_find(udev, ff_erase.request_id);
if (!req || req->code != UI_FF_ERASE) {
retval = -EINVAL;
goto out;
}
req->retval = ff_erase.retval;
complete(&req->done);
goto out;
}
size = _IOC_SIZE(cmd);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment