Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: add driver for AUO In-Cell touchscreens using pixcir ICs

Some displays from AUO have a so called in-cell touchscreen, meaning it
is built directly into the display unit.

Touchdata is gathered through PIXCIR Tango-ICs and processed in an
Atmel ATmega168P with custom firmware. Communication between the host
system and ATmega is done via I2C.

Devices using this touch solution include the Dell Streak5 and the family
of Qisda ebook readers.

The driver reports single- and multi-touch events including touch area
values.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>

authored by

Heiko Stübner and committed by
Dmitry Torokhov
5245db49 cd314fa6

+722
+13
drivers/input/touchscreen/Kconfig
··· 98 98 To compile this driver as a module, choose M here: the 99 99 module will be called atmel_mxt_ts. 100 100 101 + config TOUCHSCREEN_AUO_PIXCIR 102 + tristate "AUO in-cell touchscreen using Pixcir ICs" 103 + depends on I2C 104 + depends on GPIOLIB 105 + help 106 + Say Y here if you have a AUO display with in-cell touchscreen 107 + using Pixcir ICs. 108 + 109 + If unsure, say N. 110 + 111 + To compile this driver as a module, choose M here: the 112 + module will be called auo-pixcir-ts. 113 + 101 114 config TOUCHSCREEN_BITSY 102 115 tristate "Compaq iPAQ H3600 (Bitsy) touchscreen" 103 116 depends on SA1100_BITSY
+1
drivers/input/touchscreen/Makefile
··· 14 14 obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o 15 15 obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o 16 16 obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o 17 + obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o 17 18 obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o 18 19 obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o 19 20 obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
+652
drivers/input/touchscreen/auo-pixcir-ts.c
··· 1 + /* 2 + * Driver for AUO in-cell touchscreens 3 + * 4 + * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * loosely based on auo_touch.c from Dell Streak vendor-kernel 7 + * 8 + * Copyright (c) 2008 QUALCOMM Incorporated. 9 + * Copyright (c) 2008 QUALCOMM USA, INC. 10 + * 11 + * 12 + * This software is licensed under the terms of the GNU General Public 13 + * License version 2, as published by the Free Software Foundation, and 14 + * may be copied, distributed, and modified under those terms. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + * 21 + */ 22 + 23 + #include <linux/kernel.h> 24 + #include <linux/module.h> 25 + #include <linux/interrupt.h> 26 + #include <linux/slab.h> 27 + #include <linux/input.h> 28 + #include <linux/jiffies.h> 29 + #include <linux/i2c.h> 30 + #include <linux/mutex.h> 31 + #include <linux/delay.h> 32 + #include <linux/gpio.h> 33 + #include <linux/input/auo-pixcir-ts.h> 34 + 35 + /* 36 + * Coordinate calculation: 37 + * X1 = X1_LSB + X1_MSB*256 38 + * Y1 = Y1_LSB + Y1_MSB*256 39 + * X2 = X2_LSB + X2_MSB*256 40 + * Y2 = Y2_LSB + Y2_MSB*256 41 + */ 42 + #define AUO_PIXCIR_REG_X1_LSB 0x00 43 + #define AUO_PIXCIR_REG_X1_MSB 0x01 44 + #define AUO_PIXCIR_REG_Y1_LSB 0x02 45 + #define AUO_PIXCIR_REG_Y1_MSB 0x03 46 + #define AUO_PIXCIR_REG_X2_LSB 0x04 47 + #define AUO_PIXCIR_REG_X2_MSB 0x05 48 + #define AUO_PIXCIR_REG_Y2_LSB 0x06 49 + #define AUO_PIXCIR_REG_Y2_MSB 0x07 50 + 51 + #define AUO_PIXCIR_REG_STRENGTH 0x0d 52 + #define AUO_PIXCIR_REG_STRENGTH_X1_LSB 0x0e 53 + #define AUO_PIXCIR_REG_STRENGTH_X1_MSB 0x0f 54 + 55 + #define AUO_PIXCIR_REG_RAW_DATA_X 0x2b 56 + #define AUO_PIXCIR_REG_RAW_DATA_Y 0x4f 57 + 58 + #define AUO_PIXCIR_REG_X_SENSITIVITY 0x6f 59 + #define AUO_PIXCIR_REG_Y_SENSITIVITY 0x70 60 + #define AUO_PIXCIR_REG_INT_SETTING 0x71 61 + #define AUO_PIXCIR_REG_INT_WIDTH 0x72 62 + #define AUO_PIXCIR_REG_POWER_MODE 0x73 63 + 64 + #define AUO_PIXCIR_REG_VERSION 0x77 65 + #define AUO_PIXCIR_REG_CALIBRATE 0x78 66 + 67 + #define AUO_PIXCIR_REG_TOUCHAREA_X1 0x1e 68 + #define AUO_PIXCIR_REG_TOUCHAREA_Y1 0x1f 69 + #define AUO_PIXCIR_REG_TOUCHAREA_X2 0x20 70 + #define AUO_PIXCIR_REG_TOUCHAREA_Y2 0x21 71 + 72 + #define AUO_PIXCIR_REG_EEPROM_CALIB_X 0x42 73 + #define AUO_PIXCIR_REG_EEPROM_CALIB_Y 0xad 74 + 75 + #define AUO_PIXCIR_INT_TPNUM_MASK 0xe0 76 + #define AUO_PIXCIR_INT_TPNUM_SHIFT 5 77 + #define AUO_PIXCIR_INT_RELEASE (1 << 4) 78 + #define AUO_PIXCIR_INT_ENABLE (1 << 3) 79 + #define AUO_PIXCIR_INT_POL_HIGH (1 << 2) 80 + #define AUO_PIXCIR_INT_MODE_MASK 0x03 81 + 82 + /* 83 + * Power modes: 84 + * active: scan speed 60Hz 85 + * sleep: scan speed 10Hz can be auto-activated, wakeup on 1st touch 86 + * deep sleep: scan speed 1Hz can only be entered or left manually. 87 + */ 88 + #define AUO_PIXCIR_POWER_ACTIVE 0x00 89 + #define AUO_PIXCIR_POWER_SLEEP 0x01 90 + #define AUO_PIXCIR_POWER_DEEP_SLEEP 0x02 91 + #define AUO_PIXCIR_POWER_MASK 0x03 92 + 93 + #define AUO_PIXCIR_POWER_ALLOW_SLEEP (1 << 2) 94 + #define AUO_PIXCIR_POWER_IDLE_TIME(ms) ((ms & 0xf) << 4) 95 + 96 + #define AUO_PIXCIR_CALIBRATE 0x03 97 + 98 + #define AUO_PIXCIR_EEPROM_CALIB_X_LEN 62 99 + #define AUO_PIXCIR_EEPROM_CALIB_Y_LEN 36 100 + 101 + #define AUO_PIXCIR_RAW_DATA_X_LEN 18 102 + #define AUO_PIXCIR_RAW_DATA_Y_LEN 11 103 + 104 + #define AUO_PIXCIR_STRENGTH_ENABLE (1 << 0) 105 + 106 + /* Touchscreen absolute values */ 107 + #define AUO_PIXCIR_REPORT_POINTS 2 108 + #define AUO_PIXCIR_MAX_AREA 0xff 109 + #define AUO_PIXCIR_PENUP_TIMEOUT_MS 10 110 + 111 + struct auo_pixcir_ts { 112 + struct i2c_client *client; 113 + struct input_dev *input; 114 + char phys[32]; 115 + 116 + /* special handling for touch_indicate interupt mode */ 117 + bool touch_ind_mode; 118 + 119 + wait_queue_head_t wait; 120 + bool stopped; 121 + }; 122 + 123 + struct auo_point_t { 124 + int coord_x; 125 + int coord_y; 126 + int area_major; 127 + int area_minor; 128 + int orientation; 129 + }; 130 + 131 + static int auo_pixcir_collect_data(struct auo_pixcir_ts *ts, 132 + struct auo_point_t *point) 133 + { 134 + struct i2c_client *client = ts->client; 135 + const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; 136 + uint8_t raw_coord[8]; 137 + uint8_t raw_area[4]; 138 + int i, ret; 139 + 140 + /* touch coordinates */ 141 + ret = i2c_smbus_read_i2c_block_data(client, AUO_PIXCIR_REG_X1_LSB, 142 + 8, raw_coord); 143 + if (ret < 0) { 144 + dev_err(&client->dev, "failed to read coordinate, %d\n", ret); 145 + return ret; 146 + } 147 + 148 + /* touch area */ 149 + ret = i2c_smbus_read_i2c_block_data(client, AUO_PIXCIR_REG_TOUCHAREA_X1, 150 + 4, raw_area); 151 + if (ret < 0) { 152 + dev_err(&client->dev, "could not read touch area, %d\n", ret); 153 + return ret; 154 + } 155 + 156 + for (i = 0; i < AUO_PIXCIR_REPORT_POINTS; i++) { 157 + point[i].coord_x = 158 + raw_coord[4 * i + 1] << 8 | raw_coord[4 * i]; 159 + point[i].coord_y = 160 + raw_coord[4 * i + 3] << 8 | raw_coord[4 * i + 2]; 161 + 162 + if (point[i].coord_x > pdata->x_max || 163 + point[i].coord_y > pdata->y_max) { 164 + dev_warn(&client->dev, "coordinates (%d,%d) invalid\n", 165 + point[i].coord_x, point[i].coord_y); 166 + point[i].coord_x = point[i].coord_y = 0; 167 + } 168 + 169 + /* determine touch major, minor and orientation */ 170 + point[i].area_major = max(raw_area[2 * i], raw_area[2 * i + 1]); 171 + point[i].area_minor = min(raw_area[2 * i], raw_area[2 * i + 1]); 172 + point[i].orientation = raw_area[2 * i] > raw_area[2 * i + 1]; 173 + } 174 + 175 + return 0; 176 + } 177 + 178 + static irqreturn_t auo_pixcir_interrupt(int irq, void *dev_id) 179 + { 180 + struct auo_pixcir_ts *ts = dev_id; 181 + struct i2c_client *client = ts->client; 182 + const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; 183 + struct auo_point_t point[AUO_PIXCIR_REPORT_POINTS]; 184 + int i; 185 + int ret; 186 + int fingers = 0; 187 + int abs = -1; 188 + 189 + while (!ts->stopped) { 190 + 191 + /* check for up event in touch touch_ind_mode */ 192 + if (ts->touch_ind_mode) { 193 + if (gpio_get_value(pdata->gpio_int) == 0) { 194 + input_mt_sync(ts->input); 195 + input_report_key(ts->input, BTN_TOUCH, 0); 196 + input_sync(ts->input); 197 + break; 198 + } 199 + } 200 + 201 + ret = auo_pixcir_collect_data(ts, point); 202 + if (ret < 0) { 203 + /* we want to loop only in touch_ind_mode */ 204 + if (!ts->touch_ind_mode) 205 + break; 206 + 207 + wait_event_timeout(ts->wait, ts->stopped, 208 + msecs_to_jiffies(AUO_PIXCIR_PENUP_TIMEOUT_MS)); 209 + continue; 210 + } 211 + 212 + for (i = 0; i < AUO_PIXCIR_REPORT_POINTS; i++) { 213 + if (point[i].coord_x > 0 || point[i].coord_y > 0) { 214 + input_report_abs(ts->input, ABS_MT_POSITION_X, 215 + point[i].coord_x); 216 + input_report_abs(ts->input, ABS_MT_POSITION_Y, 217 + point[i].coord_y); 218 + input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 219 + point[i].area_major); 220 + input_report_abs(ts->input, ABS_MT_TOUCH_MINOR, 221 + point[i].area_minor); 222 + input_report_abs(ts->input, ABS_MT_ORIENTATION, 223 + point[i].orientation); 224 + input_mt_sync(ts->input); 225 + 226 + /* use first finger as source for singletouch */ 227 + if (fingers == 0) 228 + abs = i; 229 + 230 + /* number of touch points could also be queried 231 + * via i2c but would require an additional call 232 + */ 233 + fingers++; 234 + } 235 + } 236 + 237 + input_report_key(ts->input, BTN_TOUCH, fingers > 0); 238 + 239 + if (abs > -1) { 240 + input_report_abs(ts->input, ABS_X, point[abs].coord_x); 241 + input_report_abs(ts->input, ABS_Y, point[abs].coord_y); 242 + } 243 + 244 + input_sync(ts->input); 245 + 246 + /* we want to loop only in touch_ind_mode */ 247 + if (!ts->touch_ind_mode) 248 + break; 249 + 250 + wait_event_timeout(ts->wait, ts->stopped, 251 + msecs_to_jiffies(AUO_PIXCIR_PENUP_TIMEOUT_MS)); 252 + } 253 + 254 + return IRQ_HANDLED; 255 + } 256 + 257 + /* 258 + * Set the power mode of the device. 259 + * Valid modes are 260 + * - AUO_PIXCIR_POWER_ACTIVE 261 + * - AUO_PIXCIR_POWER_SLEEP - automatically left on first touch 262 + * - AUO_PIXCIR_POWER_DEEP_SLEEP 263 + */ 264 + static int auo_pixcir_power_mode(struct auo_pixcir_ts *ts, int mode) 265 + { 266 + struct i2c_client *client = ts->client; 267 + int ret; 268 + 269 + ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_POWER_MODE); 270 + if (ret < 0) { 271 + dev_err(&client->dev, "unable to read reg %Xh, %d\n", 272 + AUO_PIXCIR_REG_POWER_MODE, ret); 273 + return ret; 274 + } 275 + 276 + ret &= ~AUO_PIXCIR_POWER_MASK; 277 + ret |= mode; 278 + 279 + ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_POWER_MODE, ret); 280 + if (ret) { 281 + dev_err(&client->dev, "unable to write reg %Xh, %d\n", 282 + AUO_PIXCIR_REG_POWER_MODE, ret); 283 + return ret; 284 + } 285 + 286 + return 0; 287 + } 288 + 289 + static __devinit int auo_pixcir_int_config(struct auo_pixcir_ts *ts, 290 + int int_setting) 291 + { 292 + struct i2c_client *client = ts->client; 293 + struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; 294 + int ret; 295 + 296 + ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING); 297 + if (ret < 0) { 298 + dev_err(&client->dev, "unable to read reg %Xh, %d\n", 299 + AUO_PIXCIR_REG_INT_SETTING, ret); 300 + return ret; 301 + } 302 + 303 + ret &= ~AUO_PIXCIR_INT_MODE_MASK; 304 + ret |= int_setting; 305 + ret |= AUO_PIXCIR_INT_POL_HIGH; /* always use high for interrupts */ 306 + 307 + ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_INT_SETTING, 308 + ret); 309 + if (ret < 0) { 310 + dev_err(&client->dev, "unable to write reg %Xh, %d\n", 311 + AUO_PIXCIR_REG_INT_SETTING, ret); 312 + return ret; 313 + } 314 + 315 + ts->touch_ind_mode = pdata->int_setting == AUO_PIXCIR_INT_TOUCH_IND; 316 + 317 + return 0; 318 + } 319 + 320 + /* control the generation of interrupts on the device side */ 321 + static int auo_pixcir_int_toggle(struct auo_pixcir_ts *ts, bool enable) 322 + { 323 + struct i2c_client *client = ts->client; 324 + int ret; 325 + 326 + ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_INT_SETTING); 327 + if (ret < 0) { 328 + dev_err(&client->dev, "unable to read reg %Xh, %d\n", 329 + AUO_PIXCIR_REG_INT_SETTING, ret); 330 + return ret; 331 + } 332 + 333 + if (enable) 334 + ret |= AUO_PIXCIR_INT_ENABLE; 335 + else 336 + ret &= ~AUO_PIXCIR_INT_ENABLE; 337 + 338 + ret = i2c_smbus_write_byte_data(client, AUO_PIXCIR_REG_INT_SETTING, 339 + ret); 340 + if (ret < 0) { 341 + dev_err(&client->dev, "unable to write reg %Xh, %d\n", 342 + AUO_PIXCIR_REG_INT_SETTING, ret); 343 + return ret; 344 + } 345 + 346 + return 0; 347 + } 348 + 349 + static int auo_pixcir_start(struct auo_pixcir_ts *ts) 350 + { 351 + struct i2c_client *client = ts->client; 352 + int ret; 353 + 354 + ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_ACTIVE); 355 + if (ret < 0) { 356 + dev_err(&client->dev, "could not set power mode, %d\n", 357 + ret); 358 + return ret; 359 + } 360 + 361 + ts->stopped = false; 362 + mb(); 363 + enable_irq(client->irq); 364 + 365 + ret = auo_pixcir_int_toggle(ts, 1); 366 + if (ret < 0) { 367 + dev_err(&client->dev, "could not enable interrupt, %d\n", 368 + ret); 369 + disable_irq(client->irq); 370 + return ret; 371 + } 372 + 373 + return 0; 374 + } 375 + 376 + static int auo_pixcir_stop(struct auo_pixcir_ts *ts) 377 + { 378 + struct i2c_client *client = ts->client; 379 + int ret; 380 + 381 + ret = auo_pixcir_int_toggle(ts, 0); 382 + if (ret < 0) { 383 + dev_err(&client->dev, "could not disable interrupt, %d\n", 384 + ret); 385 + return ret; 386 + } 387 + 388 + /* disable receiving of interrupts */ 389 + disable_irq(client->irq); 390 + ts->stopped = true; 391 + mb(); 392 + wake_up(&ts->wait); 393 + 394 + return auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_DEEP_SLEEP); 395 + } 396 + 397 + static int auo_pixcir_input_open(struct input_dev *dev) 398 + { 399 + struct auo_pixcir_ts *ts = input_get_drvdata(dev); 400 + int ret; 401 + 402 + ret = auo_pixcir_start(ts); 403 + if (ret) 404 + return ret; 405 + 406 + return 0; 407 + } 408 + 409 + static void auo_pixcir_input_close(struct input_dev *dev) 410 + { 411 + struct auo_pixcir_ts *ts = input_get_drvdata(dev); 412 + 413 + auo_pixcir_stop(ts); 414 + 415 + return; 416 + } 417 + 418 + #ifdef CONFIG_PM_SLEEP 419 + static int auo_pixcir_suspend(struct device *dev) 420 + { 421 + struct i2c_client *client = to_i2c_client(dev); 422 + struct auo_pixcir_ts *ts = i2c_get_clientdata(client); 423 + struct input_dev *input = ts->input; 424 + int ret = 0; 425 + 426 + mutex_lock(&input->mutex); 427 + 428 + /* when configured as wakeup source, device should always wake system 429 + * therefore start device if necessary 430 + */ 431 + if (device_may_wakeup(&client->dev)) { 432 + /* need to start device if not open, to be wakeup source */ 433 + if (!input->users) { 434 + ret = auo_pixcir_start(ts); 435 + if (ret) 436 + goto unlock; 437 + } 438 + 439 + enable_irq_wake(client->irq); 440 + ret = auo_pixcir_power_mode(ts, AUO_PIXCIR_POWER_SLEEP); 441 + } else if (input->users) { 442 + ret = auo_pixcir_stop(ts); 443 + } 444 + 445 + unlock: 446 + mutex_unlock(&input->mutex); 447 + 448 + return ret; 449 + } 450 + 451 + static int auo_pixcir_resume(struct device *dev) 452 + { 453 + struct i2c_client *client = to_i2c_client(dev); 454 + struct auo_pixcir_ts *ts = i2c_get_clientdata(client); 455 + struct input_dev *input = ts->input; 456 + int ret = 0; 457 + 458 + mutex_lock(&input->mutex); 459 + 460 + if (device_may_wakeup(&client->dev)) { 461 + disable_irq_wake(client->irq); 462 + 463 + /* need to stop device if it was not open on suspend */ 464 + if (!input->users) { 465 + ret = auo_pixcir_stop(ts); 466 + if (ret) 467 + goto unlock; 468 + } 469 + 470 + /* device wakes automatically from SLEEP */ 471 + } else if (input->users) { 472 + ret = auo_pixcir_start(ts); 473 + } 474 + 475 + unlock: 476 + mutex_unlock(&input->mutex); 477 + 478 + return ret; 479 + } 480 + #endif 481 + 482 + static SIMPLE_DEV_PM_OPS(auo_pixcir_pm_ops, auo_pixcir_suspend, 483 + auo_pixcir_resume); 484 + 485 + static int __devinit auo_pixcir_probe(struct i2c_client *client, 486 + const struct i2c_device_id *id) 487 + { 488 + const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; 489 + struct auo_pixcir_ts *ts; 490 + struct input_dev *input_dev; 491 + int ret; 492 + 493 + if (!pdata) 494 + return -EINVAL; 495 + 496 + ts = kzalloc(sizeof(struct auo_pixcir_ts), GFP_KERNEL); 497 + if (!ts) 498 + return -ENOMEM; 499 + 500 + ret = gpio_request(pdata->gpio_int, "auo_pixcir_ts_int"); 501 + if (ret) { 502 + dev_err(&client->dev, "request of gpio %d failed, %d\n", 503 + pdata->gpio_int, ret); 504 + goto err_gpio_int; 505 + } 506 + 507 + if (pdata->init_hw) 508 + pdata->init_hw(client); 509 + 510 + ts->client = client; 511 + ts->touch_ind_mode = 0; 512 + init_waitqueue_head(&ts->wait); 513 + 514 + snprintf(ts->phys, sizeof(ts->phys), 515 + "%s/input0", dev_name(&client->dev)); 516 + 517 + input_dev = input_allocate_device(); 518 + if (!input_dev) { 519 + dev_err(&client->dev, "could not allocate input device\n"); 520 + goto err_input_alloc; 521 + } 522 + 523 + ts->input = input_dev; 524 + 525 + input_dev->name = "AUO-Pixcir touchscreen"; 526 + input_dev->phys = ts->phys; 527 + input_dev->id.bustype = BUS_I2C; 528 + input_dev->dev.parent = &client->dev; 529 + 530 + input_dev->open = auo_pixcir_input_open; 531 + input_dev->close = auo_pixcir_input_close; 532 + 533 + __set_bit(EV_ABS, input_dev->evbit); 534 + __set_bit(EV_KEY, input_dev->evbit); 535 + 536 + __set_bit(BTN_TOUCH, input_dev->keybit); 537 + 538 + /* For single touch */ 539 + input_set_abs_params(input_dev, ABS_X, 0, pdata->x_max, 0, 0); 540 + input_set_abs_params(input_dev, ABS_Y, 0, pdata->y_max, 0, 0); 541 + 542 + /* For multi touch */ 543 + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 544 + pdata->x_max, 0, 0); 545 + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 546 + pdata->y_max, 0, 0); 547 + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 548 + AUO_PIXCIR_MAX_AREA, 0, 0); 549 + input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, 0, 550 + AUO_PIXCIR_MAX_AREA, 0, 0); 551 + input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 0, 1, 0, 0); 552 + 553 + ret = i2c_smbus_read_byte_data(client, AUO_PIXCIR_REG_VERSION); 554 + if (ret < 0) 555 + goto err_fw_vers; 556 + dev_info(&client->dev, "firmware version 0x%X\n", ret); 557 + 558 + ret = auo_pixcir_int_config(ts, pdata->int_setting); 559 + if (ret) 560 + goto err_fw_vers; 561 + 562 + input_set_drvdata(ts->input, ts); 563 + ts->stopped = true; 564 + 565 + ret = request_threaded_irq(client->irq, NULL, auo_pixcir_interrupt, 566 + IRQF_TRIGGER_RISING | IRQF_ONESHOT, 567 + input_dev->name, ts); 568 + if (ret) { 569 + dev_err(&client->dev, "irq %d requested failed\n", client->irq); 570 + goto err_fw_vers; 571 + } 572 + 573 + /* stop device and put it into deep sleep until it is opened */ 574 + ret = auo_pixcir_stop(ts); 575 + if (ret < 0) 576 + goto err_input_register; 577 + 578 + ret = input_register_device(input_dev); 579 + if (ret) { 580 + dev_err(&client->dev, "could not register input device\n"); 581 + goto err_input_register; 582 + } 583 + 584 + i2c_set_clientdata(client, ts); 585 + 586 + return 0; 587 + 588 + err_input_register: 589 + free_irq(client->irq, ts); 590 + err_fw_vers: 591 + input_free_device(input_dev); 592 + err_input_alloc: 593 + if (pdata->exit_hw) 594 + pdata->exit_hw(client); 595 + gpio_free(pdata->gpio_int); 596 + err_gpio_int: 597 + kfree(ts); 598 + 599 + return ret; 600 + } 601 + 602 + static int __devexit auo_pixcir_remove(struct i2c_client *client) 603 + { 604 + struct auo_pixcir_ts *ts = i2c_get_clientdata(client); 605 + const struct auo_pixcir_ts_platdata *pdata = client->dev.platform_data; 606 + 607 + free_irq(client->irq, ts); 608 + 609 + input_unregister_device(ts->input); 610 + 611 + if (pdata->exit_hw) 612 + pdata->exit_hw(client); 613 + 614 + gpio_free(pdata->gpio_int); 615 + 616 + kfree(ts); 617 + 618 + return 0; 619 + } 620 + 621 + static const struct i2c_device_id auo_pixcir_idtable[] = { 622 + { "auo_pixcir_ts", 0 }, 623 + { } 624 + }; 625 + MODULE_DEVICE_TABLE(i2c, auo_pixcir_idtable); 626 + 627 + static struct i2c_driver auo_pixcir_driver = { 628 + .driver = { 629 + .owner = THIS_MODULE, 630 + .name = "auo_pixcir_ts", 631 + .pm = &auo_pixcir_pm_ops, 632 + }, 633 + .probe = auo_pixcir_probe, 634 + .remove = __devexit_p(auo_pixcir_remove), 635 + .id_table = auo_pixcir_idtable, 636 + }; 637 + 638 + static int __init auo_pixcir_init(void) 639 + { 640 + return i2c_add_driver(&auo_pixcir_driver); 641 + } 642 + module_init(auo_pixcir_init); 643 + 644 + static void __exit auo_pixcir_exit(void) 645 + { 646 + i2c_del_driver(&auo_pixcir_driver); 647 + } 648 + module_exit(auo_pixcir_exit); 649 + 650 + MODULE_DESCRIPTION("AUO-PIXCIR touchscreen driver"); 651 + MODULE_LICENSE("GPL v2"); 652 + MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
+56
include/linux/input/auo-pixcir-ts.h
··· 1 + /* 2 + * Driver for AUO in-cell touchscreens 3 + * 4 + * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de> 5 + * 6 + * based on auo_touch.h from Dell Streak kernel 7 + * 8 + * Copyright (c) 2008 QUALCOMM Incorporated. 9 + * Copyright (c) 2008 QUALCOMM USA, INC. 10 + * 11 + * 12 + * This software is licensed under the terms of the GNU General Public 13 + * License version 2, as published by the Free Software Foundation, and 14 + * may be copied, distributed, and modified under those terms. 15 + * 16 + * This program is distributed in the hope that it will be useful, 17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 + * GNU General Public License for more details. 20 + * 21 + */ 22 + 23 + #ifndef __AUO_PIXCIR_TS_H__ 24 + #define __AUO_PIXCIR_TS_H__ 25 + 26 + /* 27 + * Interrupt modes: 28 + * periodical: interrupt is asserted periodicaly 29 + * compare coordinates: interrupt is asserted when coordinates change 30 + * indicate touch: interrupt is asserted during touch 31 + */ 32 + #define AUO_PIXCIR_INT_PERIODICAL 0x00 33 + #define AUO_PIXCIR_INT_COMP_COORD 0x01 34 + #define AUO_PIXCIR_INT_TOUCH_IND 0x02 35 + 36 + /* 37 + * @gpio_int interrupt gpio 38 + * @int_setting one of AUO_PIXCIR_INT_* 39 + * @init_hw hardwarespecific init 40 + * @exit_hw hardwarespecific shutdown 41 + * @x_max x-resolution 42 + * @y_max y-resolution 43 + */ 44 + struct auo_pixcir_ts_platdata { 45 + int gpio_int; 46 + 47 + int int_setting; 48 + 49 + void (*init_hw)(struct i2c_client *); 50 + void (*exit_hw)(struct i2c_client *); 51 + 52 + unsigned int x_max; 53 + unsigned int y_max; 54 + }; 55 + 56 + #endif