diff options
Diffstat (limited to 'drivers/input/touchscreen')
| -rw-r--r-- | drivers/input/touchscreen/corgi_ts.c | 127 | ||||
| -rw-r--r-- | drivers/input/touchscreen/elo.c | 89 | ||||
| -rw-r--r-- | drivers/input/touchscreen/gunze.c | 66 | ||||
| -rw-r--r-- | drivers/input/touchscreen/h3600_ts_input.c | 149 | ||||
| -rw-r--r-- | drivers/input/touchscreen/hp680_ts_input.c | 50 | ||||
| -rw-r--r-- | drivers/input/touchscreen/mk712.c | 80 | ||||
| -rw-r--r-- | drivers/input/touchscreen/mtouch.c | 64 |
7 files changed, 297 insertions, 328 deletions
diff --git a/drivers/input/touchscreen/corgi_ts.c b/drivers/input/touchscreen/corgi_ts.c index 4c7fbe550365..0ba3e6562bff 100644 --- a/drivers/input/touchscreen/corgi_ts.c +++ b/drivers/input/touchscreen/corgi_ts.c | |||
| @@ -41,8 +41,7 @@ struct ts_event { | |||
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | struct corgi_ts { | 43 | struct corgi_ts { |
| 44 | char phys[32]; | 44 | struct input_dev *input; |
| 45 | struct input_dev input; | ||
| 46 | struct timer_list timer; | 45 | struct timer_list timer; |
| 47 | struct ts_event tc; | 46 | struct ts_event tc; |
| 48 | int pendown; | 47 | int pendown; |
| @@ -182,14 +181,12 @@ static void new_data(struct corgi_ts *corgi_ts, struct pt_regs *regs) | |||
| 182 | if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) | 181 | if (!corgi_ts->tc.pressure && corgi_ts->pendown == 0) |
| 183 | return; | 182 | return; |
| 184 | 183 | ||
| 185 | if (regs) | 184 | input_regs(corgi_ts->input, regs); |
| 186 | input_regs(&corgi_ts->input, regs); | 185 | input_report_abs(corgi_ts->input, ABS_X, corgi_ts->tc.x); |
| 187 | 186 | input_report_abs(corgi_ts->input, ABS_Y, corgi_ts->tc.y); | |
| 188 | input_report_abs(&corgi_ts->input, ABS_X, corgi_ts->tc.x); | 187 | input_report_abs(corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); |
| 189 | input_report_abs(&corgi_ts->input, ABS_Y, corgi_ts->tc.y); | 188 | input_report_key(corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); |
| 190 | input_report_abs(&corgi_ts->input, ABS_PRESSURE, corgi_ts->tc.pressure); | 189 | input_sync(corgi_ts->input); |
| 191 | input_report_key(&corgi_ts->input, BTN_TOUCH, (corgi_ts->pendown != 0)); | ||
| 192 | input_sync(&corgi_ts->input); | ||
| 193 | } | 190 | } |
| 194 | 191 | ||
| 195 | static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs) | 192 | static void ts_interrupt_main(struct corgi_ts *corgi_ts, int isTimer, struct pt_regs *regs) |
| @@ -234,34 +231,32 @@ static irqreturn_t ts_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 234 | } | 231 | } |
| 235 | 232 | ||
| 236 | #ifdef CONFIG_PM | 233 | #ifdef CONFIG_PM |
| 237 | static int corgits_suspend(struct device *dev, pm_message_t state, uint32_t level) | 234 | static int corgits_suspend(struct device *dev, pm_message_t state) |
| 238 | { | 235 | { |
| 239 | if (level == SUSPEND_POWER_DOWN) { | 236 | struct corgi_ts *corgi_ts = dev_get_drvdata(dev); |
| 240 | struct corgi_ts *corgi_ts = dev_get_drvdata(dev); | ||
| 241 | |||
| 242 | if (corgi_ts->pendown) { | ||
| 243 | del_timer_sync(&corgi_ts->timer); | ||
| 244 | corgi_ts->tc.pressure = 0; | ||
| 245 | new_data(corgi_ts, NULL); | ||
| 246 | corgi_ts->pendown = 0; | ||
| 247 | } | ||
| 248 | corgi_ts->power_mode = PWR_MODE_SUSPEND; | ||
| 249 | 237 | ||
| 250 | corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | 238 | if (corgi_ts->pendown) { |
| 239 | del_timer_sync(&corgi_ts->timer); | ||
| 240 | corgi_ts->tc.pressure = 0; | ||
| 241 | new_data(corgi_ts, NULL); | ||
| 242 | corgi_ts->pendown = 0; | ||
| 251 | } | 243 | } |
| 244 | corgi_ts->power_mode = PWR_MODE_SUSPEND; | ||
| 245 | |||
| 246 | corgi_ssp_ads7846_putget((1u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
| 247 | |||
| 252 | return 0; | 248 | return 0; |
| 253 | } | 249 | } |
| 254 | 250 | ||
| 255 | static int corgits_resume(struct device *dev, uint32_t level) | 251 | static int corgits_resume(struct device *dev) |
| 256 | { | 252 | { |
| 257 | if (level == RESUME_POWER_ON) { | 253 | struct corgi_ts *corgi_ts = dev_get_drvdata(dev); |
| 258 | struct corgi_ts *corgi_ts = dev_get_drvdata(dev); | 254 | |
| 255 | corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
| 256 | /* Enable Falling Edge */ | ||
| 257 | set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); | ||
| 258 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | ||
| 259 | 259 | ||
| 260 | corgi_ssp_ads7846_putget((4u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | ||
| 261 | /* Enable Falling Edge */ | ||
| 262 | set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); | ||
| 263 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | ||
| 264 | } | ||
| 265 | return 0; | 260 | return 0; |
| 266 | } | 261 | } |
| 267 | #else | 262 | #else |
| @@ -273,39 +268,44 @@ static int __init corgits_probe(struct device *dev) | |||
| 273 | { | 268 | { |
| 274 | struct corgi_ts *corgi_ts; | 269 | struct corgi_ts *corgi_ts; |
| 275 | struct platform_device *pdev = to_platform_device(dev); | 270 | struct platform_device *pdev = to_platform_device(dev); |
| 271 | struct input_dev *input_dev; | ||
| 272 | int err = -ENOMEM; | ||
| 276 | 273 | ||
| 277 | if (!(corgi_ts = kmalloc(sizeof(struct corgi_ts), GFP_KERNEL))) | 274 | corgi_ts = kzalloc(sizeof(struct corgi_ts), GFP_KERNEL); |
| 278 | return -ENOMEM; | 275 | input_dev = input_allocate_device(); |
| 276 | if (!corgi_ts || !input_dev) | ||
| 277 | goto fail; | ||
| 279 | 278 | ||
| 280 | dev_set_drvdata(dev, corgi_ts); | 279 | dev_set_drvdata(dev, corgi_ts); |
| 281 | 280 | ||
| 282 | memset(corgi_ts, 0, sizeof(struct corgi_ts)); | ||
| 283 | |||
| 284 | corgi_ts->machinfo = dev->platform_data; | 281 | corgi_ts->machinfo = dev->platform_data; |
| 285 | corgi_ts->irq_gpio = platform_get_irq(pdev, 0); | 282 | corgi_ts->irq_gpio = platform_get_irq(pdev, 0); |
| 286 | 283 | ||
| 287 | if (corgi_ts->irq_gpio < 0) { | 284 | if (corgi_ts->irq_gpio < 0) { |
| 288 | kfree(corgi_ts); | 285 | err = -ENODEV; |
| 289 | return -ENODEV; | 286 | goto fail; |
| 290 | } | 287 | } |
| 291 | 288 | ||
| 292 | init_input_dev(&corgi_ts->input); | 289 | corgi_ts->input = input_dev; |
| 293 | corgi_ts->input.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
| 294 | corgi_ts->input.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 295 | input_set_abs_params(&corgi_ts->input, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); | ||
| 296 | input_set_abs_params(&corgi_ts->input, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); | ||
| 297 | input_set_abs_params(&corgi_ts->input, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0); | ||
| 298 | 290 | ||
| 299 | strcpy(corgi_ts->phys, "corgits/input0"); | 291 | init_timer(&corgi_ts->timer); |
| 292 | corgi_ts->timer.data = (unsigned long) corgi_ts; | ||
| 293 | corgi_ts->timer.function = corgi_ts_timer; | ||
| 300 | 294 | ||
| 301 | corgi_ts->input.private = corgi_ts; | 295 | input_dev->name = "Corgi Touchscreen"; |
| 302 | corgi_ts->input.name = "Corgi Touchscreen"; | 296 | input_dev->phys = "corgits/input0"; |
| 303 | corgi_ts->input.dev = dev; | 297 | input_dev->id.bustype = BUS_HOST; |
| 304 | corgi_ts->input.phys = corgi_ts->phys; | 298 | input_dev->id.vendor = 0x0001; |
| 305 | corgi_ts->input.id.bustype = BUS_HOST; | 299 | input_dev->id.product = 0x0002; |
| 306 | corgi_ts->input.id.vendor = 0x0001; | 300 | input_dev->id.version = 0x0100; |
| 307 | corgi_ts->input.id.product = 0x0002; | 301 | input_dev->cdev.dev = dev; |
| 308 | corgi_ts->input.id.version = 0x0100; | 302 | input_dev->private = corgi_ts; |
| 303 | |||
| 304 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
| 305 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 306 | input_set_abs_params(input_dev, ABS_X, X_AXIS_MIN, X_AXIS_MAX, 0, 0); | ||
| 307 | input_set_abs_params(input_dev, ABS_Y, Y_AXIS_MIN, Y_AXIS_MAX, 0, 0); | ||
| 308 | input_set_abs_params(input_dev, ABS_PRESSURE, PRESSURE_MIN, PRESSURE_MAX, 0, 0); | ||
| 309 | 309 | ||
| 310 | pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN); | 310 | pxa_gpio_mode(IRQ_TO_GPIO(corgi_ts->irq_gpio) | GPIO_IN); |
| 311 | 311 | ||
| @@ -319,25 +319,24 @@ static int __init corgits_probe(struct device *dev) | |||
| 319 | corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS); | 319 | corgi_ssp_ads7846_putget((5u << ADSCTRL_ADR_SH) | ADSCTRL_STS); |
| 320 | mdelay(5); | 320 | mdelay(5); |
| 321 | 321 | ||
| 322 | init_timer(&corgi_ts->timer); | ||
| 323 | corgi_ts->timer.data = (unsigned long) corgi_ts; | ||
| 324 | corgi_ts->timer.function = corgi_ts_timer; | ||
| 325 | |||
| 326 | input_register_device(&corgi_ts->input); | ||
| 327 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | ||
| 328 | |||
| 329 | if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) { | 322 | if (request_irq(corgi_ts->irq_gpio, ts_interrupt, SA_INTERRUPT, "ts", corgi_ts)) { |
| 330 | input_unregister_device(&corgi_ts->input); | 323 | err = -EBUSY; |
| 331 | kfree(corgi_ts); | 324 | goto fail; |
| 332 | return -EBUSY; | ||
| 333 | } | 325 | } |
| 334 | 326 | ||
| 327 | input_register_device(corgi_ts->input); | ||
| 328 | |||
| 329 | corgi_ts->power_mode = PWR_MODE_ACTIVE; | ||
| 330 | |||
| 335 | /* Enable Falling Edge */ | 331 | /* Enable Falling Edge */ |
| 336 | set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); | 332 | set_irq_type(corgi_ts->irq_gpio, IRQT_FALLING); |
| 337 | 333 | ||
| 338 | printk(KERN_INFO "input: Corgi Touchscreen Registered\n"); | ||
| 339 | |||
| 340 | return 0; | 334 | return 0; |
| 335 | |||
| 336 | fail: input_free_device(input_dev); | ||
| 337 | kfree(corgi_ts); | ||
| 338 | return err; | ||
| 339 | |||
| 341 | } | 340 | } |
| 342 | 341 | ||
| 343 | static int corgits_remove(struct device *dev) | 342 | static int corgits_remove(struct device *dev) |
| @@ -347,7 +346,7 @@ static int corgits_remove(struct device *dev) | |||
| 347 | free_irq(corgi_ts->irq_gpio, NULL); | 346 | free_irq(corgi_ts->irq_gpio, NULL); |
| 348 | del_timer_sync(&corgi_ts->timer); | 347 | del_timer_sync(&corgi_ts->timer); |
| 349 | corgi_ts->machinfo->put_hsync(); | 348 | corgi_ts->machinfo->put_hsync(); |
| 350 | input_unregister_device(&corgi_ts->input); | 349 | input_unregister_device(corgi_ts->input); |
| 351 | kfree(corgi_ts); | 350 | kfree(corgi_ts); |
| 352 | return 0; | 351 | return 0; |
| 353 | } | 352 | } |
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index 3cdc9cab688d..c86a2eb310fd 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
| @@ -36,14 +36,12 @@ MODULE_LICENSE("GPL"); | |||
| 36 | 36 | ||
| 37 | #define ELO_MAX_LENGTH 10 | 37 | #define ELO_MAX_LENGTH 10 |
| 38 | 38 | ||
| 39 | static char *elo_name = "Elo Serial TouchScreen"; | ||
| 40 | |||
| 41 | /* | 39 | /* |
| 42 | * Per-touchscreen data. | 40 | * Per-touchscreen data. |
| 43 | */ | 41 | */ |
| 44 | 42 | ||
| 45 | struct elo { | 43 | struct elo { |
| 46 | struct input_dev dev; | 44 | struct input_dev *dev; |
| 47 | struct serio *serio; | 45 | struct serio *serio; |
| 48 | int id; | 46 | int id; |
| 49 | int idx; | 47 | int idx; |
| @@ -54,7 +52,7 @@ struct elo { | |||
| 54 | 52 | ||
| 55 | static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs) | 53 | static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs) |
| 56 | { | 54 | { |
| 57 | struct input_dev *dev = &elo->dev; | 55 | struct input_dev *dev = elo->dev; |
| 58 | 56 | ||
| 59 | elo->csum += elo->data[elo->idx] = data; | 57 | elo->csum += elo->data[elo->idx] = data; |
| 60 | 58 | ||
| @@ -80,7 +78,7 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r | |||
| 80 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | 78 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); |
| 81 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | 79 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); |
| 82 | input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]); | 80 | input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]); |
| 83 | input_report_key(dev, BTN_TOUCH, elo->data[2] & 3); | 81 | input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]); |
| 84 | input_sync(dev); | 82 | input_sync(dev); |
| 85 | } | 83 | } |
| 86 | elo->idx = 0; | 84 | elo->idx = 0; |
| @@ -91,7 +89,7 @@ static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_r | |||
| 91 | 89 | ||
| 92 | static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs) | 90 | static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs) |
| 93 | { | 91 | { |
| 94 | struct input_dev *dev = &elo->dev; | 92 | struct input_dev *dev = elo->dev; |
| 95 | 93 | ||
| 96 | elo->data[elo->idx] = data; | 94 | elo->data[elo->idx] = data; |
| 97 | 95 | ||
| @@ -129,7 +127,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re | |||
| 129 | case 5: | 127 | case 5: |
| 130 | if ((data & 0xf0) == 0) { | 128 | if ((data & 0xf0) == 0) { |
| 131 | input_report_abs(dev, ABS_PRESSURE, elo->data[5]); | 129 | input_report_abs(dev, ABS_PRESSURE, elo->data[5]); |
| 132 | input_report_key(dev, BTN_TOUCH, elo->data[5]); | 130 | input_report_key(dev, BTN_TOUCH, !!elo->data[5]); |
| 133 | } | 131 | } |
| 134 | input_sync(dev); | 132 | input_sync(dev); |
| 135 | elo->idx = 0; | 133 | elo->idx = 0; |
| @@ -139,7 +137,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re | |||
| 139 | 137 | ||
| 140 | static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs) | 138 | static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs) |
| 141 | { | 139 | { |
| 142 | struct input_dev *dev = &elo->dev; | 140 | struct input_dev *dev = elo->dev; |
| 143 | 141 | ||
| 144 | elo->data[elo->idx] = data; | 142 | elo->data[elo->idx] = data; |
| 145 | 143 | ||
| @@ -191,7 +189,7 @@ static void elo_disconnect(struct serio *serio) | |||
| 191 | { | 189 | { |
| 192 | struct elo* elo = serio_get_drvdata(serio); | 190 | struct elo* elo = serio_get_drvdata(serio); |
| 193 | 191 | ||
| 194 | input_unregister_device(&elo->dev); | 192 | input_unregister_device(elo->dev); |
| 195 | serio_close(serio); | 193 | serio_close(serio); |
| 196 | serio_set_drvdata(serio, NULL); | 194 | serio_set_drvdata(serio, NULL); |
| 197 | kfree(elo); | 195 | kfree(elo); |
| @@ -206,67 +204,68 @@ static void elo_disconnect(struct serio *serio) | |||
| 206 | static int elo_connect(struct serio *serio, struct serio_driver *drv) | 204 | static int elo_connect(struct serio *serio, struct serio_driver *drv) |
| 207 | { | 205 | { |
| 208 | struct elo *elo; | 206 | struct elo *elo; |
| 207 | struct input_dev *input_dev; | ||
| 209 | int err; | 208 | int err; |
| 210 | 209 | ||
| 211 | if (!(elo = kmalloc(sizeof(struct elo), GFP_KERNEL))) | 210 | elo = kzalloc(sizeof(struct elo), GFP_KERNEL); |
| 212 | return -ENOMEM; | 211 | input_dev = input_allocate_device(); |
| 212 | if (!elo || !input_dev) { | ||
| 213 | err = -ENOMEM; | ||
| 214 | goto fail; | ||
| 215 | } | ||
| 213 | 216 | ||
| 214 | memset(elo, 0, sizeof(struct elo)); | 217 | elo->serio = serio; |
| 218 | elo->id = serio->id.id; | ||
| 219 | elo->dev = input_dev; | ||
| 220 | snprintf(elo->phys, sizeof(elo->phys), "%s/input0", serio->phys); | ||
| 215 | 221 | ||
| 216 | init_input_dev(&elo->dev); | 222 | input_dev->private = elo; |
| 217 | elo->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | 223 | input_dev->name = "Elo Serial TouchScreen"; |
| 218 | elo->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 224 | input_dev->phys = elo->phys; |
| 225 | input_dev->id.bustype = BUS_RS232; | ||
| 226 | input_dev->id.vendor = SERIO_ELO; | ||
| 227 | input_dev->id.product = elo->id; | ||
| 228 | input_dev->id.version = 0x0100; | ||
| 229 | input_dev->cdev.dev = &serio->dev; | ||
| 219 | 230 | ||
| 220 | elo->id = serio->id.id; | 231 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
| 232 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 221 | 233 | ||
| 222 | switch (elo->id) { | 234 | switch (elo->id) { |
| 223 | 235 | ||
| 224 | case 0: /* 10-byte protocol */ | 236 | case 0: /* 10-byte protocol */ |
| 225 | input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0); | 237 | input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); |
| 226 | input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0); | 238 | input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); |
| 227 | input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 255, 0, 0); | 239 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); |
| 228 | break; | 240 | break; |
| 229 | 241 | ||
| 230 | case 1: /* 6-byte protocol */ | 242 | case 1: /* 6-byte protocol */ |
| 231 | input_set_abs_params(&elo->dev, ABS_PRESSURE, 0, 15, 0, 0); | 243 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 15, 0, 0); |
| 232 | 244 | ||
| 233 | case 2: /* 4-byte protocol */ | 245 | case 2: /* 4-byte protocol */ |
| 234 | input_set_abs_params(&elo->dev, ABS_X, 96, 4000, 0, 0); | 246 | input_set_abs_params(input_dev, ABS_X, 96, 4000, 0, 0); |
| 235 | input_set_abs_params(&elo->dev, ABS_Y, 96, 4000, 0, 0); | 247 | input_set_abs_params(input_dev, ABS_Y, 96, 4000, 0, 0); |
| 236 | break; | 248 | break; |
| 237 | 249 | ||
| 238 | case 3: /* 3-byte protocol */ | 250 | case 3: /* 3-byte protocol */ |
| 239 | input_set_abs_params(&elo->dev, ABS_X, 0, 255, 0, 0); | 251 | input_set_abs_params(input_dev, ABS_X, 0, 255, 0, 0); |
| 240 | input_set_abs_params(&elo->dev, ABS_Y, 0, 255, 0, 0); | 252 | input_set_abs_params(input_dev, ABS_Y, 0, 255, 0, 0); |
| 241 | break; | 253 | break; |
| 242 | } | 254 | } |
| 243 | 255 | ||
| 244 | elo->serio = serio; | ||
| 245 | |||
| 246 | sprintf(elo->phys, "%s/input0", serio->phys); | ||
| 247 | |||
| 248 | elo->dev.private = elo; | ||
| 249 | elo->dev.name = elo_name; | ||
| 250 | elo->dev.phys = elo->phys; | ||
| 251 | elo->dev.id.bustype = BUS_RS232; | ||
| 252 | elo->dev.id.vendor = SERIO_ELO; | ||
| 253 | elo->dev.id.product = elo->id; | ||
| 254 | elo->dev.id.version = 0x0100; | ||
| 255 | |||
| 256 | serio_set_drvdata(serio, elo); | 256 | serio_set_drvdata(serio, elo); |
| 257 | 257 | ||
| 258 | err = serio_open(serio, drv); | 258 | err = serio_open(serio, drv); |
| 259 | if (err) { | 259 | if (err) |
| 260 | serio_set_drvdata(serio, NULL); | 260 | goto fail; |
| 261 | kfree(elo); | ||
| 262 | return err; | ||
| 263 | } | ||
| 264 | |||
| 265 | input_register_device(&elo->dev); | ||
| 266 | |||
| 267 | printk(KERN_INFO "input: %s on %s\n", elo_name, serio->phys); | ||
| 268 | 261 | ||
| 262 | input_register_device(elo->dev); | ||
| 269 | return 0; | 263 | return 0; |
| 264 | |||
| 265 | fail: serio_set_drvdata(serio, NULL); | ||
| 266 | input_free_device(input_dev); | ||
| 267 | kfree(elo); | ||
| 268 | return err; | ||
| 270 | } | 269 | } |
| 271 | 270 | ||
| 272 | /* | 271 | /* |
diff --git a/drivers/input/touchscreen/gunze.c b/drivers/input/touchscreen/gunze.c index 53a27e43dd23..466da190ceec 100644 --- a/drivers/input/touchscreen/gunze.c +++ b/drivers/input/touchscreen/gunze.c | |||
| @@ -48,14 +48,12 @@ MODULE_LICENSE("GPL"); | |||
| 48 | 48 | ||
| 49 | #define GUNZE_MAX_LENGTH 10 | 49 | #define GUNZE_MAX_LENGTH 10 |
| 50 | 50 | ||
| 51 | static char *gunze_name = "Gunze AHL-51S TouchScreen"; | ||
| 52 | |||
| 53 | /* | 51 | /* |
| 54 | * Per-touchscreen data. | 52 | * Per-touchscreen data. |
| 55 | */ | 53 | */ |
| 56 | 54 | ||
| 57 | struct gunze { | 55 | struct gunze { |
| 58 | struct input_dev dev; | 56 | struct input_dev *dev; |
| 59 | struct serio *serio; | 57 | struct serio *serio; |
| 60 | int idx; | 58 | int idx; |
| 61 | unsigned char data[GUNZE_MAX_LENGTH]; | 59 | unsigned char data[GUNZE_MAX_LENGTH]; |
| @@ -64,7 +62,7 @@ struct gunze { | |||
| 64 | 62 | ||
| 65 | static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) | 63 | static void gunze_process_packet(struct gunze* gunze, struct pt_regs *regs) |
| 66 | { | 64 | { |
| 67 | struct input_dev *dev = &gunze->dev; | 65 | struct input_dev *dev = gunze->dev; |
| 68 | 66 | ||
| 69 | if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || | 67 | if (gunze->idx != GUNZE_MAX_LENGTH || gunze->data[5] != ',' || |
| 70 | (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { | 68 | (gunze->data[0] != 'T' && gunze->data[0] != 'R')) { |
| @@ -100,11 +98,13 @@ static irqreturn_t gunze_interrupt(struct serio *serio, | |||
| 100 | 98 | ||
| 101 | static void gunze_disconnect(struct serio *serio) | 99 | static void gunze_disconnect(struct serio *serio) |
| 102 | { | 100 | { |
| 103 | struct gunze* gunze = serio_get_drvdata(serio); | 101 | struct gunze *gunze = serio_get_drvdata(serio); |
| 104 | 102 | ||
| 105 | input_unregister_device(&gunze->dev); | 103 | input_get_device(gunze->dev); |
| 104 | input_unregister_device(gunze->dev); | ||
| 106 | serio_close(serio); | 105 | serio_close(serio); |
| 107 | serio_set_drvdata(serio, NULL); | 106 | serio_set_drvdata(serio, NULL); |
| 107 | input_put_device(gunze->dev); | ||
| 108 | kfree(gunze); | 108 | kfree(gunze); |
| 109 | } | 109 | } |
| 110 | 110 | ||
| @@ -117,45 +117,45 @@ static void gunze_disconnect(struct serio *serio) | |||
| 117 | static int gunze_connect(struct serio *serio, struct serio_driver *drv) | 117 | static int gunze_connect(struct serio *serio, struct serio_driver *drv) |
| 118 | { | 118 | { |
| 119 | struct gunze *gunze; | 119 | struct gunze *gunze; |
| 120 | struct input_dev *input_dev; | ||
| 120 | int err; | 121 | int err; |
| 121 | 122 | ||
| 122 | if (!(gunze = kmalloc(sizeof(struct gunze), GFP_KERNEL))) | 123 | gunze = kzalloc(sizeof(struct gunze), GFP_KERNEL); |
| 123 | return -ENOMEM; | 124 | input_dev = input_allocate_device(); |
| 124 | 125 | if (!gunze || !input_dev) { | |
| 125 | memset(gunze, 0, sizeof(struct gunze)); | 126 | err = -ENOMEM; |
| 126 | 127 | goto fail; | |
| 127 | init_input_dev(&gunze->dev); | 128 | } |
| 128 | gunze->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
| 129 | gunze->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 130 | input_set_abs_params(&gunze->dev, ABS_X, 24, 1000, 0, 0); | ||
| 131 | input_set_abs_params(&gunze->dev, ABS_Y, 24, 1000, 0, 0); | ||
| 132 | 129 | ||
| 133 | gunze->serio = serio; | 130 | gunze->serio = serio; |
| 134 | 131 | gunze->dev = input_dev; | |
| 135 | sprintf(gunze->phys, "%s/input0", serio->phys); | 132 | sprintf(gunze->phys, "%s/input0", serio->phys); |
| 136 | 133 | ||
| 137 | gunze->dev.private = gunze; | 134 | input_dev->private = gunze; |
| 138 | gunze->dev.name = gunze_name; | 135 | input_dev->name = "Gunze AHL-51S TouchScreen"; |
| 139 | gunze->dev.phys = gunze->phys; | 136 | input_dev->phys = gunze->phys; |
| 140 | gunze->dev.id.bustype = BUS_RS232; | 137 | input_dev->id.bustype = BUS_RS232; |
| 141 | gunze->dev.id.vendor = SERIO_GUNZE; | 138 | input_dev->id.vendor = SERIO_GUNZE; |
| 142 | gunze->dev.id.product = 0x0051; | 139 | input_dev->id.product = 0x0051; |
| 143 | gunze->dev.id.version = 0x0100; | 140 | input_dev->id.version = 0x0100; |
| 141 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
| 142 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 143 | input_set_abs_params(input_dev, ABS_X, 24, 1000, 0, 0); | ||
| 144 | input_set_abs_params(input_dev, ABS_Y, 24, 1000, 0, 0); | ||
| 144 | 145 | ||
| 145 | serio_set_drvdata(serio, gunze); | 146 | serio_set_drvdata(serio, gunze); |
| 146 | 147 | ||
| 147 | err = serio_open(serio, drv); | 148 | err = serio_open(serio, drv); |
| 148 | if (err) { | 149 | if (err) |
| 149 | serio_set_drvdata(serio, NULL); | 150 | goto fail; |
| 150 | kfree(gunze); | ||
| 151 | return err; | ||
| 152 | } | ||
| 153 | |||
| 154 | input_register_device(&gunze->dev); | ||
| 155 | |||
| 156 | printk(KERN_INFO "input: %s on %s\n", gunze_name, serio->phys); | ||
| 157 | 151 | ||
| 152 | input_register_device(gunze->dev); | ||
| 158 | return 0; | 153 | return 0; |
| 154 | |||
| 155 | fail: serio_set_drvdata(serio, NULL); | ||
| 156 | input_free_device(input_dev); | ||
| 157 | kfree(gunze); | ||
| 158 | return err; | ||
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | /* | 161 | /* |
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index bcfa1e36f957..a18d56bdafd9 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
| @@ -39,7 +39,6 @@ | |||
| 39 | #include <linux/serio.h> | 39 | #include <linux/serio.h> |
| 40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
| 41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
| 42 | #include <linux/pm.h> | ||
| 43 | 42 | ||
| 44 | /* SA1100 serial defines */ | 43 | /* SA1100 serial defines */ |
| 45 | #include <asm/arch/hardware.h> | 44 | #include <asm/arch/hardware.h> |
| @@ -93,16 +92,12 @@ MODULE_LICENSE("GPL"); | |||
| 93 | #define H3600_SCANCODE_LEFT 8 /* 8 -> left */ | 92 | #define H3600_SCANCODE_LEFT 8 /* 8 -> left */ |
| 94 | #define H3600_SCANCODE_DOWN 9 /* 9 -> down */ | 93 | #define H3600_SCANCODE_DOWN 9 /* 9 -> down */ |
| 95 | 94 | ||
| 96 | static char *h3600_name = "H3600 TouchScreen"; | ||
| 97 | |||
| 98 | /* | 95 | /* |
| 99 | * Per-touchscreen data. | 96 | * Per-touchscreen data. |
| 100 | */ | 97 | */ |
| 101 | struct h3600_dev { | 98 | struct h3600_dev { |
| 102 | struct input_dev dev; | 99 | struct input_dev *dev; |
| 103 | struct pm_dev *pm_dev; | ||
| 104 | struct serio *serio; | 100 | struct serio *serio; |
| 105 | struct pm_dev *pm_dev; | ||
| 106 | unsigned char event; /* event ID from packet */ | 101 | unsigned char event; /* event ID from packet */ |
| 107 | unsigned char chksum; | 102 | unsigned char chksum; |
| 108 | unsigned char len; | 103 | unsigned char len; |
| @@ -163,33 +158,6 @@ unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr) | |||
| 163 | return 0; | 158 | return 0; |
| 164 | } | 159 | } |
| 165 | 160 | ||
| 166 | static int suspended = 0; | ||
| 167 | static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, | ||
| 168 | void *data) | ||
| 169 | { | ||
| 170 | struct input_dev *dev = (struct input_dev *) data; | ||
| 171 | |||
| 172 | switch (req) { | ||
| 173 | case PM_SUSPEND: /* enter D1-D3 */ | ||
| 174 | suspended = 1; | ||
| 175 | h3600_flite_power(dev, FLITE_PWR_OFF); | ||
| 176 | break; | ||
| 177 | case PM_BLANK: | ||
| 178 | if (!suspended) | ||
| 179 | h3600_flite_power(dev, FLITE_PWR_OFF); | ||
| 180 | break; | ||
| 181 | case PM_RESUME: /* enter D0 */ | ||
| 182 | /* same as unblank */ | ||
| 183 | case PM_UNBLANK: | ||
| 184 | if (suspended) { | ||
| 185 | //initSerial(); | ||
| 186 | suspended = 0; | ||
| 187 | } | ||
| 188 | h3600_flite_power(dev, FLITE_PWR_ON); | ||
| 189 | break; | ||
| 190 | } | ||
| 191 | return 0; | ||
| 192 | } | ||
| 193 | #endif | 161 | #endif |
| 194 | 162 | ||
| 195 | /* | 163 | /* |
| @@ -199,7 +167,7 @@ static int h3600ts_pm_callback(struct pm_dev *pm_dev, pm_request_t req, | |||
| 199 | */ | 167 | */ |
| 200 | static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) | 168 | static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) |
| 201 | { | 169 | { |
| 202 | struct input_dev *dev = &ts->dev; | 170 | struct input_dev *dev = ts->dev; |
| 203 | static int touched = 0; | 171 | static int touched = 0; |
| 204 | int key, down = 0; | 172 | int key, down = 0; |
| 205 | 173 | ||
| @@ -295,6 +263,7 @@ static void h3600ts_process_packet(struct h3600_dev *ts, struct pt_regs *regs) | |||
| 295 | static int h3600ts_event(struct input_dev *dev, unsigned int type, | 263 | static int h3600ts_event(struct input_dev *dev, unsigned int type, |
| 296 | unsigned int code, int value) | 264 | unsigned int code, int value) |
| 297 | { | 265 | { |
| 266 | #if 0 | ||
| 298 | struct h3600_dev *ts = dev->private; | 267 | struct h3600_dev *ts = dev->private; |
| 299 | 268 | ||
| 300 | switch (type) { | 269 | switch (type) { |
| @@ -304,6 +273,8 @@ static int h3600ts_event(struct input_dev *dev, unsigned int type, | |||
| 304 | } | 273 | } |
| 305 | } | 274 | } |
| 306 | return -1; | 275 | return -1; |
| 276 | #endif | ||
| 277 | return 0; | ||
| 307 | } | 278 | } |
| 308 | 279 | ||
| 309 | /* | 280 | /* |
| @@ -380,14 +351,48 @@ static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data, | |||
| 380 | static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | 351 | static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) |
| 381 | { | 352 | { |
| 382 | struct h3600_dev *ts; | 353 | struct h3600_dev *ts; |
| 354 | struct input_dev *input_dev; | ||
| 383 | int err; | 355 | int err; |
| 384 | 356 | ||
| 385 | if (!(ts = kmalloc(sizeof(struct h3600_dev), GFP_KERNEL))) | 357 | ts = kzalloc(sizeof(struct h3600_dev), GFP_KERNEL); |
| 386 | return -ENOMEM; | 358 | input_dev = input_allocate_device(); |
| 359 | if (!ts || !input_dev) { | ||
| 360 | err = -ENOMEM; | ||
| 361 | goto fail1; | ||
| 362 | } | ||
| 387 | 363 | ||
| 388 | memset(ts, 0, sizeof(struct h3600_dev)); | 364 | ts->serio = serio; |
| 365 | ts->dev = input_dev; | ||
| 366 | sprintf(ts->phys, "%s/input0", serio->phys); | ||
| 389 | 367 | ||
| 390 | init_input_dev(&ts->dev); | 368 | input_dev->name = "H3600 TouchScreen"; |
| 369 | input_dev->phys = ts->phys; | ||
| 370 | input_dev->id.bustype = BUS_RS232; | ||
| 371 | input_dev->id.vendor = SERIO_H3600; | ||
| 372 | input_dev->id.product = 0x0666; /* FIXME !!! We can ask the hardware */ | ||
| 373 | input_dev->id.version = 0x0100; | ||
| 374 | input_dev->cdev.dev = &serio->dev; | ||
| 375 | input_dev->private = ts; | ||
| 376 | |||
| 377 | input_dev->event = h3600ts_event; | ||
| 378 | |||
| 379 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); | ||
| 380 | input_dev->ledbit[0] = BIT(LED_SLEEP); | ||
| 381 | input_set_abs_params(input_dev, ABS_X, 60, 985, 0, 0); | ||
| 382 | input_set_abs_params(input_dev, ABS_Y, 35, 1024, 0, 0); | ||
| 383 | |||
| 384 | set_bit(KEY_RECORD, input_dev->keybit); | ||
| 385 | set_bit(KEY_Q, input_dev->keybit); | ||
| 386 | set_bit(KEY_PROG1, input_dev->keybit); | ||
| 387 | set_bit(KEY_PROG2, input_dev->keybit); | ||
| 388 | set_bit(KEY_PROG3, input_dev->keybit); | ||
| 389 | set_bit(KEY_UP, input_dev->keybit); | ||
| 390 | set_bit(KEY_RIGHT, input_dev->keybit); | ||
| 391 | set_bit(KEY_LEFT, input_dev->keybit); | ||
| 392 | set_bit(KEY_DOWN, input_dev->keybit); | ||
| 393 | set_bit(KEY_ENTER, input_dev->keybit); | ||
| 394 | set_bit(KEY_SUSPEND, input_dev->keybit); | ||
| 395 | set_bit(BTN_TOUCH, input_dev->keybit); | ||
| 391 | 396 | ||
| 392 | /* Device specific stuff */ | 397 | /* Device specific stuff */ |
| 393 | set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES); | 398 | set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES); |
| @@ -397,73 +402,35 @@ static int h3600ts_connect(struct serio *serio, struct serio_driver *drv) | |||
| 397 | SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, | 402 | SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, |
| 398 | "h3600_action", &ts->dev)) { | 403 | "h3600_action", &ts->dev)) { |
| 399 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); | 404 | printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n"); |
| 400 | kfree(ts); | 405 | err = -EBUSY; |
| 401 | return -EBUSY; | 406 | goto fail2; |
| 402 | } | 407 | } |
| 403 | 408 | ||
| 404 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, | 409 | if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler, |
| 405 | SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, | 410 | SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM, |
| 406 | "h3600_suspend", &ts->dev)) { | 411 | "h3600_suspend", &ts->dev)) { |
| 407 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); | ||
| 408 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); | 412 | printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n"); |
| 409 | kfree(ts); | 413 | err = -EBUSY; |
| 410 | return -EBUSY; | 414 | goto fail3; |
| 411 | } | 415 | } |
| 412 | 416 | ||
| 413 | /* Now we have things going we setup our input device */ | ||
| 414 | ts->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_LED) | BIT(EV_PWR); | ||
| 415 | ts->dev.ledbit[0] = BIT(LED_SLEEP); | ||
| 416 | input_set_abs_params(&ts->dev, ABS_X, 60, 985, 0, 0); | ||
| 417 | input_set_abs_params(&ts->dev, ABS_Y, 35, 1024, 0, 0); | ||
| 418 | |||
| 419 | set_bit(KEY_RECORD, ts->dev.keybit); | ||
| 420 | set_bit(KEY_Q, ts->dev.keybit); | ||
| 421 | set_bit(KEY_PROG1, ts->dev.keybit); | ||
| 422 | set_bit(KEY_PROG2, ts->dev.keybit); | ||
| 423 | set_bit(KEY_PROG3, ts->dev.keybit); | ||
| 424 | set_bit(KEY_UP, ts->dev.keybit); | ||
| 425 | set_bit(KEY_RIGHT, ts->dev.keybit); | ||
| 426 | set_bit(KEY_LEFT, ts->dev.keybit); | ||
| 427 | set_bit(KEY_DOWN, ts->dev.keybit); | ||
| 428 | set_bit(KEY_ENTER, ts->dev.keybit); | ||
| 429 | ts->dev.keybit[LONG(BTN_TOUCH)] |= BIT(BTN_TOUCH); | ||
| 430 | ts->dev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND); | ||
| 431 | |||
| 432 | ts->serio = serio; | ||
| 433 | |||
| 434 | sprintf(ts->phys, "%s/input0", serio->phys); | ||
| 435 | |||
| 436 | ts->dev.event = h3600ts_event; | ||
| 437 | ts->dev.private = ts; | ||
| 438 | ts->dev.name = h3600_name; | ||
| 439 | ts->dev.phys = ts->phys; | ||
| 440 | ts->dev.id.bustype = BUS_RS232; | ||
| 441 | ts->dev.id.vendor = SERIO_H3600; | ||
| 442 | ts->dev.id.product = 0x0666; /* FIXME !!! We can ask the hardware */ | ||
| 443 | ts->dev.id.version = 0x0100; | ||
| 444 | |||
| 445 | serio_set_drvdata(serio, ts); | 417 | serio_set_drvdata(serio, ts); |
| 446 | 418 | ||
| 447 | err = serio_open(serio, drv); | 419 | err = serio_open(serio, drv); |
| 448 | if (err) { | 420 | if (err) |
| 449 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts); | ||
| 450 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts); | ||
| 451 | serio_set_drvdata(serio, NULL); | ||
| 452 | kfree(ts); | ||
| 453 | return err; | 421 | return err; |
| 454 | } | ||
| 455 | 422 | ||
| 456 | //h3600_flite_control(1, 25); /* default brightness */ | 423 | //h3600_flite_control(1, 25); /* default brightness */ |
| 457 | #ifdef CONFIG_PM | 424 | input_register_device(ts->dev); |
| 458 | ts->pm_dev = pm_register(PM_ILLUMINATION_DEV, PM_SYS_LIGHT, | ||
| 459 | h3600ts_pm_callback); | ||
| 460 | printk("registered pm callback\n"); | ||
| 461 | #endif | ||
| 462 | input_register_device(&ts->dev); | ||
| 463 | |||
| 464 | printk(KERN_INFO "input: %s on %s\n", h3600_name, serio->phys); | ||
| 465 | 425 | ||
| 466 | return 0; | 426 | return 0; |
| 427 | |||
| 428 | fail3: free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev); | ||
| 429 | fail2: free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev); | ||
| 430 | fail1: serio_set_drvdata(serio, NULL); | ||
| 431 | input_free_device(input_dev); | ||
| 432 | kfree(ts); | ||
| 433 | return err; | ||
| 467 | } | 434 | } |
| 468 | 435 | ||
| 469 | /* | 436 | /* |
| @@ -476,9 +443,11 @@ static void h3600ts_disconnect(struct serio *serio) | |||
| 476 | 443 | ||
| 477 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); | 444 | free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev); |
| 478 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); | 445 | free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev); |
| 479 | input_unregister_device(&ts->dev); | 446 | input_get_device(ts->dev); |
| 447 | input_unregister_device(ts->dev); | ||
| 480 | serio_close(serio); | 448 | serio_close(serio); |
| 481 | serio_set_drvdata(serio, NULL); | 449 | serio_set_drvdata(serio, NULL); |
| 450 | input_put_device(ts->dev); | ||
| 482 | kfree(ts); | 451 | kfree(ts); |
| 483 | } | 452 | } |
| 484 | 453 | ||
diff --git a/drivers/input/touchscreen/hp680_ts_input.c b/drivers/input/touchscreen/hp680_ts_input.c index 7e1404441eca..957dd5a1b15e 100644 --- a/drivers/input/touchscreen/hp680_ts_input.c +++ b/drivers/input/touchscreen/hp680_ts_input.c | |||
| @@ -21,10 +21,8 @@ | |||
| 21 | 21 | ||
| 22 | static void do_softint(void *data); | 22 | static void do_softint(void *data); |
| 23 | 23 | ||
| 24 | static struct input_dev hp680_ts_dev; | 24 | static struct input_dev *hp680_ts_dev; |
| 25 | static DECLARE_WORK(work, do_softint, 0); | 25 | static DECLARE_WORK(work, do_softint, 0); |
| 26 | static char *hp680_ts_name = "HP Jornada touchscreen"; | ||
| 27 | static char *hp680_ts_phys = "input0"; | ||
| 28 | 26 | ||
| 29 | static void do_softint(void *data) | 27 | static void do_softint(void *data) |
| 30 | { | 28 | { |
| @@ -58,14 +56,14 @@ static void do_softint(void *data) | |||
| 58 | } | 56 | } |
| 59 | 57 | ||
| 60 | if (touched) { | 58 | if (touched) { |
| 61 | input_report_key(&hp680_ts_dev, BTN_TOUCH, 1); | 59 | input_report_key(hp680_ts_dev, BTN_TOUCH, 1); |
| 62 | input_report_abs(&hp680_ts_dev, ABS_X, absx); | 60 | input_report_abs(hp680_ts_dev, ABS_X, absx); |
| 63 | input_report_abs(&hp680_ts_dev, ABS_Y, absy); | 61 | input_report_abs(hp680_ts_dev, ABS_Y, absy); |
| 64 | } else { | 62 | } else { |
| 65 | input_report_key(&hp680_ts_dev, BTN_TOUCH, 0); | 63 | input_report_key(hp680_ts_dev, BTN_TOUCH, 0); |
| 66 | } | 64 | } |
| 67 | 65 | ||
| 68 | input_sync(&hp680_ts_dev); | 66 | input_sync(hp680_ts_dev); |
| 69 | enable_irq(HP680_TS_IRQ); | 67 | enable_irq(HP680_TS_IRQ); |
| 70 | } | 68 | } |
| 71 | 69 | ||
| @@ -92,27 +90,29 @@ static int __init hp680_ts_init(void) | |||
| 92 | scpcr |= SCPCR_TS_ENABLE; | 90 | scpcr |= SCPCR_TS_ENABLE; |
| 93 | ctrl_outw(scpcr, SCPCR); | 91 | ctrl_outw(scpcr, SCPCR); |
| 94 | 92 | ||
| 95 | memset(&hp680_ts_dev, 0, sizeof(hp680_ts_dev)); | 93 | hp680_ts_dev = input_allocate_device(); |
| 96 | init_input_dev(&hp680_ts_dev); | 94 | if (!hp680_ts_dev) |
| 95 | return -ENOMEM; | ||
| 97 | 96 | ||
| 98 | hp680_ts_dev.evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); | 97 | hp680_ts_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); |
| 99 | hp680_ts_dev.absbit[0] = BIT(ABS_X) | BIT(ABS_Y); | 98 | hp680_ts_dev->absbit[0] = BIT(ABS_X) | BIT(ABS_Y); |
| 100 | hp680_ts_dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 99 | hp680_ts_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
| 101 | 100 | ||
| 102 | hp680_ts_dev.absmin[ABS_X] = HP680_TS_ABS_X_MIN; | 101 | hp680_ts_dev->absmin[ABS_X] = HP680_TS_ABS_X_MIN; |
| 103 | hp680_ts_dev.absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; | 102 | hp680_ts_dev->absmin[ABS_Y] = HP680_TS_ABS_Y_MIN; |
| 104 | hp680_ts_dev.absmax[ABS_X] = HP680_TS_ABS_X_MAX; | 103 | hp680_ts_dev->absmax[ABS_X] = HP680_TS_ABS_X_MAX; |
| 105 | hp680_ts_dev.absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; | 104 | hp680_ts_dev->absmax[ABS_Y] = HP680_TS_ABS_Y_MAX; |
| 106 | 105 | ||
| 107 | hp680_ts_dev.name = hp680_ts_name; | 106 | hp680_ts_dev->name = "HP Jornada touchscreen"; |
| 108 | hp680_ts_dev.phys = hp680_ts_phys; | 107 | hp680_ts_dev->phys = "hp680_ts/input0"; |
| 109 | input_register_device(&hp680_ts_dev); | ||
| 110 | 108 | ||
| 111 | if (request_irq | 109 | input_register_device(hp680_ts_dev); |
| 112 | (HP680_TS_IRQ, hp680_ts_interrupt, SA_INTERRUPT, MODNAME, 0) < 0) { | 110 | |
| 113 | printk(KERN_ERR "hp680_touchscreen.c : Can't allocate irq %d\n", | 111 | if (request_irq(HP680_TS_IRQ, hp680_ts_interrupt, |
| 112 | SA_INTERRUPT, MODNAME, 0) < 0) { | ||
| 113 | printk(KERN_ERR "hp680_touchscreen.c: Can't allocate irq %d\n", | ||
| 114 | HP680_TS_IRQ); | 114 | HP680_TS_IRQ); |
| 115 | input_unregister_device(&hp680_ts_dev); | 115 | input_unregister_device(hp680_ts_dev); |
| 116 | return -EBUSY; | 116 | return -EBUSY; |
| 117 | } | 117 | } |
| 118 | 118 | ||
| @@ -124,7 +124,7 @@ static void __exit hp680_ts_exit(void) | |||
| 124 | free_irq(HP680_TS_IRQ, 0); | 124 | free_irq(HP680_TS_IRQ, 0); |
| 125 | cancel_delayed_work(&work); | 125 | cancel_delayed_work(&work); |
| 126 | flush_scheduled_work(); | 126 | flush_scheduled_work(); |
| 127 | input_unregister_device(&hp680_ts_dev); | 127 | input_unregister_device(hp680_ts_dev); |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | module_init(hp680_ts_init); | 130 | module_init(hp680_ts_init); |
diff --git a/drivers/input/touchscreen/mk712.c b/drivers/input/touchscreen/mk712.c index afaaebe5225b..4844d250a5eb 100644 --- a/drivers/input/touchscreen/mk712.c +++ b/drivers/input/touchscreen/mk712.c | |||
| @@ -77,7 +77,7 @@ MODULE_PARM_DESC(irq, "IRQ of MK712 touchscreen controller"); | |||
| 77 | #define MK712_READ_ONE_POINT 0x20 | 77 | #define MK712_READ_ONE_POINT 0x20 |
| 78 | #define MK712_POWERUP 0x40 | 78 | #define MK712_POWERUP 0x40 |
| 79 | 79 | ||
| 80 | static struct input_dev mk712_dev; | 80 | static struct input_dev *mk712_dev; |
| 81 | static DEFINE_SPINLOCK(mk712_lock); | 81 | static DEFINE_SPINLOCK(mk712_lock); |
| 82 | 82 | ||
| 83 | static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 83 | static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
| @@ -88,7 +88,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 88 | static unsigned short last_y; | 88 | static unsigned short last_y; |
| 89 | 89 | ||
| 90 | spin_lock(&mk712_lock); | 90 | spin_lock(&mk712_lock); |
| 91 | input_regs(&mk712_dev, regs); | 91 | input_regs(mk712_dev, regs); |
| 92 | 92 | ||
| 93 | status = inb(mk712_io + MK712_STATUS); | 93 | status = inb(mk712_io + MK712_STATUS); |
| 94 | 94 | ||
| @@ -100,7 +100,7 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 100 | if (~status & MK712_STATUS_TOUCH) | 100 | if (~status & MK712_STATUS_TOUCH) |
| 101 | { | 101 | { |
| 102 | debounce = 1; | 102 | debounce = 1; |
| 103 | input_report_key(&mk712_dev, BTN_TOUCH, 0); | 103 | input_report_key(mk712_dev, BTN_TOUCH, 0); |
| 104 | goto end; | 104 | goto end; |
| 105 | } | 105 | } |
| 106 | 106 | ||
| @@ -110,15 +110,15 @@ static irqreturn_t mk712_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 110 | goto end; | 110 | goto end; |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | input_report_key(&mk712_dev, BTN_TOUCH, 1); | 113 | input_report_key(mk712_dev, BTN_TOUCH, 1); |
| 114 | input_report_abs(&mk712_dev, ABS_X, last_x); | 114 | input_report_abs(mk712_dev, ABS_X, last_x); |
| 115 | input_report_abs(&mk712_dev, ABS_Y, last_y); | 115 | input_report_abs(mk712_dev, ABS_Y, last_y); |
| 116 | 116 | ||
| 117 | end: | 117 | end: |
| 118 | 118 | ||
| 119 | last_x = inw(mk712_io + MK712_X) & 0x0fff; | 119 | last_x = inw(mk712_io + MK712_X) & 0x0fff; |
| 120 | last_y = inw(mk712_io + MK712_Y) & 0x0fff; | 120 | last_y = inw(mk712_io + MK712_Y) & 0x0fff; |
| 121 | input_sync(&mk712_dev); | 121 | input_sync(mk712_dev); |
| 122 | spin_unlock(&mk712_lock); | 122 | spin_unlock(&mk712_lock); |
| 123 | return IRQ_HANDLED; | 123 | return IRQ_HANDLED; |
| 124 | } | 124 | } |
| @@ -154,30 +154,11 @@ static void mk712_close(struct input_dev *dev) | |||
| 154 | spin_unlock_irqrestore(&mk712_lock, flags); | 154 | spin_unlock_irqrestore(&mk712_lock, flags); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static struct input_dev mk712_dev = { | ||
| 158 | .evbit = { BIT(EV_KEY) | BIT(EV_ABS) }, | ||
| 159 | .keybit = { [LONG(BTN_TOUCH)] = BIT(BTN_TOUCH) }, | ||
| 160 | .absbit = { BIT(ABS_X) | BIT(ABS_Y) }, | ||
| 161 | .open = mk712_open, | ||
| 162 | .close = mk712_close, | ||
| 163 | .name = "ICS MicroClock MK712 TouchScreen", | ||
| 164 | .phys = "isa0260/input0", | ||
| 165 | .absmin = { [ABS_X] = 0, [ABS_Y] = 0 }, | ||
| 166 | .absmax = { [ABS_X] = 0xfff, [ABS_Y] = 0xfff }, | ||
| 167 | .absfuzz = { [ABS_X] = 88, [ABS_Y] = 88 }, | ||
| 168 | .id = { | ||
| 169 | .bustype = BUS_ISA, | ||
| 170 | .vendor = 0x0005, | ||
| 171 | .product = 0x0001, | ||
| 172 | .version = 0x0100, | ||
| 173 | }, | ||
| 174 | }; | ||
| 175 | |||
| 176 | int __init mk712_init(void) | 157 | int __init mk712_init(void) |
| 177 | { | 158 | { |
| 159 | int err; | ||
| 178 | 160 | ||
| 179 | if(!request_region(mk712_io, 8, "mk712")) | 161 | if (!request_region(mk712_io, 8, "mk712")) { |
| 180 | { | ||
| 181 | printk(KERN_WARNING "mk712: unable to get IO region\n"); | 162 | printk(KERN_WARNING "mk712: unable to get IO region\n"); |
| 182 | return -ENODEV; | 163 | return -ENODEV; |
| 183 | } | 164 | } |
| @@ -188,28 +169,49 @@ int __init mk712_init(void) | |||
| 188 | (inw(mk712_io + MK712_Y) & 0xf000) || | 169 | (inw(mk712_io + MK712_Y) & 0xf000) || |
| 189 | (inw(mk712_io + MK712_STATUS) & 0xf333)) { | 170 | (inw(mk712_io + MK712_STATUS) & 0xf333)) { |
| 190 | printk(KERN_WARNING "mk712: device not present\n"); | 171 | printk(KERN_WARNING "mk712: device not present\n"); |
| 191 | release_region(mk712_io, 8); | 172 | err = -ENODEV; |
| 192 | return -ENODEV; | 173 | goto fail; |
| 193 | } | 174 | } |
| 194 | 175 | ||
| 195 | if(request_irq(mk712_irq, mk712_interrupt, 0, "mk712", &mk712_dev)) | 176 | if (!(mk712_dev = input_allocate_device())) { |
| 196 | { | 177 | printk(KERN_ERR "mk712: not enough memory\n"); |
| 197 | printk(KERN_WARNING "mk712: unable to get IRQ\n"); | 178 | err = -ENOMEM; |
| 198 | release_region(mk712_io, 8); | 179 | goto fail; |
| 199 | return -EBUSY; | ||
| 200 | } | 180 | } |
| 201 | 181 | ||
| 202 | input_register_device(&mk712_dev); | 182 | mk712_dev->name = "ICS MicroClock MK712 TouchScreen"; |
| 183 | mk712_dev->phys = "isa0260/input0"; | ||
| 184 | mk712_dev->id.bustype = BUS_ISA; | ||
| 185 | mk712_dev->id.vendor = 0x0005; | ||
| 186 | mk712_dev->id.product = 0x0001; | ||
| 187 | mk712_dev->id.version = 0x0100; | ||
| 188 | |||
| 189 | mk712_dev->open = mk712_open; | ||
| 190 | mk712_dev->close = mk712_close; | ||
| 203 | 191 | ||
| 204 | printk(KERN_INFO "input: ICS MicroClock MK712 TouchScreen at %#x irq %d\n", mk712_io, mk712_irq); | 192 | mk712_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); |
| 193 | mk712_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 194 | input_set_abs_params(mk712_dev, ABS_X, 0, 0xfff, 88, 0); | ||
| 195 | input_set_abs_params(mk712_dev, ABS_Y, 0, 0xfff, 88, 0); | ||
| 205 | 196 | ||
| 197 | if (request_irq(mk712_irq, mk712_interrupt, 0, "mk712", mk712_dev)) { | ||
| 198 | printk(KERN_WARNING "mk712: unable to get IRQ\n"); | ||
| 199 | err = -EBUSY; | ||
| 200 | goto fail; | ||
| 201 | } | ||
| 202 | |||
| 203 | input_register_device(mk712_dev); | ||
| 206 | return 0; | 204 | return 0; |
| 205 | |||
| 206 | fail: input_free_device(mk712_dev); | ||
| 207 | release_region(mk712_io, 8); | ||
| 208 | return err; | ||
| 207 | } | 209 | } |
| 208 | 210 | ||
| 209 | static void __exit mk712_exit(void) | 211 | static void __exit mk712_exit(void) |
| 210 | { | 212 | { |
| 211 | input_unregister_device(&mk712_dev); | 213 | input_unregister_device(mk712_dev); |
| 212 | free_irq(mk712_irq, &mk712_dev); | 214 | free_irq(mk712_irq, mk712_dev); |
| 213 | release_region(mk712_io, 8); | 215 | release_region(mk712_io, 8); |
| 214 | } | 216 | } |
| 215 | 217 | ||
diff --git a/drivers/input/touchscreen/mtouch.c b/drivers/input/touchscreen/mtouch.c index aa8ee7842179..1d0d37eeef6e 100644 --- a/drivers/input/touchscreen/mtouch.c +++ b/drivers/input/touchscreen/mtouch.c | |||
| @@ -51,14 +51,12 @@ MODULE_LICENSE("GPL"); | |||
| 51 | #define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3]) | 51 | #define MTOUCH_GET_YC(data) (((data[4])<<7) | data[3]) |
| 52 | #define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0]) | 52 | #define MTOUCH_GET_TOUCHED(data) (MTOUCH_FORMAT_TABLET_TOUCH_BIT & data[0]) |
| 53 | 53 | ||
| 54 | static char *mtouch_name = "MicroTouch Serial TouchScreen"; | ||
| 55 | |||
| 56 | /* | 54 | /* |
| 57 | * Per-touchscreen data. | 55 | * Per-touchscreen data. |
| 58 | */ | 56 | */ |
| 59 | 57 | ||
| 60 | struct mtouch { | 58 | struct mtouch { |
| 61 | struct input_dev dev; | 59 | struct input_dev *dev; |
| 62 | struct serio *serio; | 60 | struct serio *serio; |
| 63 | int idx; | 61 | int idx; |
| 64 | unsigned char data[MTOUCH_MAX_LENGTH]; | 62 | unsigned char data[MTOUCH_MAX_LENGTH]; |
| @@ -67,7 +65,7 @@ struct mtouch { | |||
| 67 | 65 | ||
| 68 | static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs) | 66 | static void mtouch_process_format_tablet(struct mtouch *mtouch, struct pt_regs *regs) |
| 69 | { | 67 | { |
| 70 | struct input_dev *dev = &mtouch->dev; | 68 | struct input_dev *dev = mtouch->dev; |
| 71 | 69 | ||
| 72 | if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) { | 70 | if (MTOUCH_FORMAT_TABLET_LENGTH == ++mtouch->idx) { |
| 73 | input_regs(dev, regs); | 71 | input_regs(dev, regs); |
| @@ -116,9 +114,11 @@ static void mtouch_disconnect(struct serio *serio) | |||
| 116 | { | 114 | { |
| 117 | struct mtouch* mtouch = serio_get_drvdata(serio); | 115 | struct mtouch* mtouch = serio_get_drvdata(serio); |
| 118 | 116 | ||
| 119 | input_unregister_device(&mtouch->dev); | 117 | input_get_device(mtouch->dev); |
| 118 | input_unregister_device(mtouch->dev); | ||
| 120 | serio_close(serio); | 119 | serio_close(serio); |
| 121 | serio_set_drvdata(serio, NULL); | 120 | serio_set_drvdata(serio, NULL); |
| 121 | input_put_device(mtouch->dev); | ||
| 122 | kfree(mtouch); | 122 | kfree(mtouch); |
| 123 | } | 123 | } |
| 124 | 124 | ||
| @@ -131,46 +131,46 @@ static void mtouch_disconnect(struct serio *serio) | |||
| 131 | static int mtouch_connect(struct serio *serio, struct serio_driver *drv) | 131 | static int mtouch_connect(struct serio *serio, struct serio_driver *drv) |
| 132 | { | 132 | { |
| 133 | struct mtouch *mtouch; | 133 | struct mtouch *mtouch; |
| 134 | struct input_dev *input_dev; | ||
| 134 | int err; | 135 | int err; |
| 135 | 136 | ||
| 136 | if (!(mtouch = kmalloc(sizeof(*mtouch), GFP_KERNEL))) | 137 | mtouch = kzalloc(sizeof(struct mtouch), GFP_KERNEL); |
| 137 | return -ENOMEM; | 138 | input_dev = input_allocate_device(); |
| 138 | 139 | if (!mtouch || !input_dev) { | |
| 139 | memset(mtouch, 0, sizeof(*mtouch)); | 140 | err = -ENOMEM; |
| 140 | 141 | goto fail; | |
| 141 | init_input_dev(&mtouch->dev); | 142 | } |
| 142 | mtouch->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
| 143 | mtouch->dev.keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 144 | |||
| 145 | input_set_abs_params(&mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); | ||
| 146 | input_set_abs_params(&mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0); | ||
| 147 | 143 | ||
| 148 | mtouch->serio = serio; | 144 | mtouch->serio = serio; |
| 149 | 145 | mtouch->dev = input_dev; | |
| 150 | sprintf(mtouch->phys, "%s/input0", serio->phys); | 146 | sprintf(mtouch->phys, "%s/input0", serio->phys); |
| 151 | 147 | ||
| 152 | mtouch->dev.private = mtouch; | 148 | input_dev->private = mtouch; |
| 153 | mtouch->dev.name = mtouch_name; | 149 | input_dev->name = "MicroTouch Serial TouchScreen"; |
| 154 | mtouch->dev.phys = mtouch->phys; | 150 | input_dev->phys = mtouch->phys; |
| 155 | mtouch->dev.id.bustype = BUS_RS232; | 151 | input_dev->id.bustype = BUS_RS232; |
| 156 | mtouch->dev.id.vendor = SERIO_MICROTOUCH; | 152 | input_dev->id.vendor = SERIO_MICROTOUCH; |
| 157 | mtouch->dev.id.product = 0; | 153 | input_dev->id.product = 0; |
| 158 | mtouch->dev.id.version = 0x0100; | 154 | input_dev->id.version = 0x0100; |
| 155 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
| 156 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | ||
| 157 | input_set_abs_params(mtouch->dev, ABS_X, MTOUCH_MIN_XC, MTOUCH_MAX_XC, 0, 0); | ||
| 158 | input_set_abs_params(mtouch->dev, ABS_Y, MTOUCH_MIN_YC, MTOUCH_MAX_YC, 0, 0); | ||
| 159 | 159 | ||
| 160 | serio_set_drvdata(serio, mtouch); | 160 | serio_set_drvdata(serio, mtouch); |
| 161 | 161 | ||
| 162 | err = serio_open(serio, drv); | 162 | err = serio_open(serio, drv); |
| 163 | if (err) { | 163 | if (err) |
| 164 | serio_set_drvdata(serio, NULL); | 164 | goto fail; |
| 165 | kfree(mtouch); | ||
| 166 | return err; | ||
| 167 | } | ||
| 168 | |||
| 169 | input_register_device(&mtouch->dev); | ||
| 170 | 165 | ||
| 171 | printk(KERN_INFO "input: %s on %s\n", mtouch->dev.name, serio->phys); | 166 | input_register_device(mtouch->dev); |
| 172 | 167 | ||
| 173 | return 0; | 168 | return 0; |
| 169 | |||
| 170 | fail: serio_set_drvdata(serio, NULL); | ||
| 171 | input_free_device(input_dev); | ||
| 172 | kfree(mtouch); | ||
| 173 | return err; | ||
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | /* | 176 | /* |
