blob: c6f6a04ec6730d9650056e9a90de53675fdd20bf [file] [log] [blame]
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -07001/*
2 * Copyright (C) ST-Ericsson SA 2010
3 * Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
4 * License terms:GNU General Public License (GPL) version 2
5 */
6
7#include <linux/kernel.h>
8#include <linux/delay.h>
9#include <linux/interrupt.h>
10#include <linux/i2c.h>
11#include <linux/workqueue.h>
12#include <linux/input.h>
13#include <linux/input/bu21013.h>
14#include <linux/slab.h>
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -080015#include <linux/regulator/consumer.h>
Paul Gortmakerd2d84422011-07-03 13:53:48 -040016#include <linux/module.h>
Lee Jones31fbcda2012-09-28 10:29:07 +010017#include <linux/gpio.h>
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -070018
19#define PEN_DOWN_INTR 0
20#define MAX_FINGERS 2
21#define RESET_DELAY 30
22#define PENUP_TIMEOUT (10)
23#define DELTA_MIN 16
24#define MASK_BITS 0x03
25#define SHIFT_8 8
26#define SHIFT_2 2
27#define LENGTH_OF_BUFFER 11
28#define I2C_RETRY_COUNT 5
29
30#define BU21013_SENSORS_BTN_0_7_REG 0x70
31#define BU21013_SENSORS_BTN_8_15_REG 0x71
32#define BU21013_SENSORS_BTN_16_23_REG 0x72
33#define BU21013_X1_POS_MSB_REG 0x73
34#define BU21013_X1_POS_LSB_REG 0x74
35#define BU21013_Y1_POS_MSB_REG 0x75
36#define BU21013_Y1_POS_LSB_REG 0x76
37#define BU21013_X2_POS_MSB_REG 0x77
38#define BU21013_X2_POS_LSB_REG 0x78
39#define BU21013_Y2_POS_MSB_REG 0x79
40#define BU21013_Y2_POS_LSB_REG 0x7A
41#define BU21013_INT_CLR_REG 0xE8
42#define BU21013_INT_MODE_REG 0xE9
43#define BU21013_GAIN_REG 0xEA
44#define BU21013_OFFSET_MODE_REG 0xEB
45#define BU21013_XY_EDGE_REG 0xEC
46#define BU21013_RESET_REG 0xED
47#define BU21013_CALIB_REG 0xEE
48#define BU21013_DONE_REG 0xEF
49#define BU21013_SENSOR_0_7_REG 0xF0
50#define BU21013_SENSOR_8_15_REG 0xF1
51#define BU21013_SENSOR_16_23_REG 0xF2
52#define BU21013_POS_MODE1_REG 0xF3
53#define BU21013_POS_MODE2_REG 0xF4
54#define BU21013_CLK_MODE_REG 0xF5
55#define BU21013_IDLE_REG 0xFA
56#define BU21013_FILTER_REG 0xFB
57#define BU21013_TH_ON_REG 0xFC
58#define BU21013_TH_OFF_REG 0xFD
59
60
61#define BU21013_RESET_ENABLE 0x01
62
63#define BU21013_SENSORS_EN_0_7 0x3F
64#define BU21013_SENSORS_EN_8_15 0xFC
65#define BU21013_SENSORS_EN_16_23 0x1F
66
67#define BU21013_POS_MODE1_0 0x02
68#define BU21013_POS_MODE1_1 0x04
69#define BU21013_POS_MODE1_2 0x08
70
71#define BU21013_POS_MODE2_ZERO 0x01
72#define BU21013_POS_MODE2_AVG1 0x02
73#define BU21013_POS_MODE2_AVG2 0x04
74#define BU21013_POS_MODE2_EN_XY 0x08
75#define BU21013_POS_MODE2_EN_RAW 0x10
76#define BU21013_POS_MODE2_MULTI 0x80
77
78#define BU21013_CLK_MODE_DIV 0x01
79#define BU21013_CLK_MODE_EXT 0x02
80#define BU21013_CLK_MODE_CALIB 0x80
81
82#define BU21013_IDLET_0 0x01
83#define BU21013_IDLET_1 0x02
84#define BU21013_IDLET_2 0x04
85#define BU21013_IDLET_3 0x08
86#define BU21013_IDLE_INTERMIT_EN 0x10
87
88#define BU21013_DELTA_0_6 0x7F
89#define BU21013_FILTER_EN 0x80
90
91#define BU21013_INT_MODE_LEVEL 0x00
92#define BU21013_INT_MODE_EDGE 0x01
93
94#define BU21013_GAIN_0 0x01
95#define BU21013_GAIN_1 0x02
96#define BU21013_GAIN_2 0x04
97
98#define BU21013_OFFSET_MODE_DEFAULT 0x00
99#define BU21013_OFFSET_MODE_MOVE 0x01
100#define BU21013_OFFSET_MODE_DISABLE 0x02
101
102#define BU21013_TH_ON_0 0x01
103#define BU21013_TH_ON_1 0x02
104#define BU21013_TH_ON_2 0x04
105#define BU21013_TH_ON_3 0x08
106#define BU21013_TH_ON_4 0x10
107#define BU21013_TH_ON_5 0x20
108#define BU21013_TH_ON_6 0x40
109#define BU21013_TH_ON_7 0x80
110#define BU21013_TH_ON_MAX 0xFF
111
112#define BU21013_TH_OFF_0 0x01
113#define BU21013_TH_OFF_1 0x02
114#define BU21013_TH_OFF_2 0x04
115#define BU21013_TH_OFF_3 0x08
116#define BU21013_TH_OFF_4 0x10
117#define BU21013_TH_OFF_5 0x20
118#define BU21013_TH_OFF_6 0x40
119#define BU21013_TH_OFF_7 0x80
120#define BU21013_TH_OFF_MAX 0xFF
121
122#define BU21013_X_EDGE_0 0x01
123#define BU21013_X_EDGE_1 0x02
124#define BU21013_X_EDGE_2 0x04
125#define BU21013_X_EDGE_3 0x08
126#define BU21013_Y_EDGE_0 0x10
127#define BU21013_Y_EDGE_1 0x20
128#define BU21013_Y_EDGE_2 0x40
129#define BU21013_Y_EDGE_3 0x80
130
131#define BU21013_DONE 0x01
132#define BU21013_NUMBER_OF_X_SENSORS (6)
133#define BU21013_NUMBER_OF_Y_SENSORS (11)
134
135#define DRIVER_TP "bu21013_tp"
136
137/**
138 * struct bu21013_ts_data - touch panel data structure
139 * @client: pointer to the i2c client
140 * @wait: variable to wait_queue_head_t structure
141 * @touch_stopped: touch stop flag
142 * @chip: pointer to the touch panel controller
143 * @in_dev: pointer to the input device structure
144 * @intr_pin: interrupt pin value
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800145 * @regulator: pointer to the Regulator used for touch screen
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700146 *
147 * Touch panel device data structure
148 */
149struct bu21013_ts_data {
150 struct i2c_client *client;
151 wait_queue_head_t wait;
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700152 const struct bu21013_platform_device *chip;
153 struct input_dev *in_dev;
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800154 struct regulator *regulator;
Lee Jones31fbcda2012-09-28 10:29:07 +0100155 unsigned int irq;
156 unsigned int intr_pin;
157 bool touch_stopped;
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700158};
159
160/**
161 * bu21013_read_block_data(): read the touch co-ordinates
162 * @data: bu21013_ts_data structure pointer
163 * @buf: byte pointer
164 *
165 * Read the touch co-ordinates using i2c read block into buffer
166 * and returns integer.
167 */
168static int bu21013_read_block_data(struct bu21013_ts_data *data, u8 *buf)
169{
170 int ret, i;
171
172 for (i = 0; i < I2C_RETRY_COUNT; i++) {
173 ret = i2c_smbus_read_i2c_block_data
174 (data->client, BU21013_SENSORS_BTN_0_7_REG,
175 LENGTH_OF_BUFFER, buf);
176 if (ret == LENGTH_OF_BUFFER)
177 return 0;
178 }
179 return -EINVAL;
180}
181
182/**
183 * bu21013_do_touch_report(): Get the touch co-ordinates
184 * @data: bu21013_ts_data structure pointer
185 *
186 * Get the touch co-ordinates from touch sensor registers and writes
187 * into device structure and returns integer.
188 */
189static int bu21013_do_touch_report(struct bu21013_ts_data *data)
190{
191 u8 buf[LENGTH_OF_BUFFER];
192 unsigned int pos_x[2], pos_y[2];
193 bool has_x_sensors, has_y_sensors;
194 int finger_down_count = 0;
195 int i;
196
197 if (data == NULL)
198 return -EINVAL;
199
200 if (bu21013_read_block_data(data, buf) < 0)
201 return -EINVAL;
202
203 has_x_sensors = hweight32(buf[0] & BU21013_SENSORS_EN_0_7);
204 has_y_sensors = hweight32(((buf[1] & BU21013_SENSORS_EN_8_15) |
205 ((buf[2] & BU21013_SENSORS_EN_16_23) << SHIFT_8)) >> SHIFT_2);
206 if (!has_x_sensors || !has_y_sensors)
207 return 0;
208
209 for (i = 0; i < MAX_FINGERS; i++) {
210 const u8 *p = &buf[4 * i + 3];
211 unsigned int x = p[0] << SHIFT_2 | (p[1] & MASK_BITS);
212 unsigned int y = p[2] << SHIFT_2 | (p[3] & MASK_BITS);
213 if (x == 0 || y == 0)
214 continue;
215 pos_x[finger_down_count] = x;
216 pos_y[finger_down_count] = y;
217 finger_down_count++;
218 }
219
220 if (finger_down_count) {
221 if (finger_down_count == 2 &&
222 (abs(pos_x[0] - pos_x[1]) < DELTA_MIN ||
223 abs(pos_y[0] - pos_y[1]) < DELTA_MIN)) {
224 return 0;
225 }
226
227 for (i = 0; i < finger_down_count; i++) {
228 if (data->chip->x_flip)
229 pos_x[i] = data->chip->touch_x_max - pos_x[i];
230 if (data->chip->y_flip)
231 pos_y[i] = data->chip->touch_y_max - pos_y[i];
232
233 input_report_abs(data->in_dev,
234 ABS_MT_POSITION_X, pos_x[i]);
235 input_report_abs(data->in_dev,
236 ABS_MT_POSITION_Y, pos_y[i]);
237 input_mt_sync(data->in_dev);
238 }
239 } else
240 input_mt_sync(data->in_dev);
241
242 input_sync(data->in_dev);
243
244 return 0;
245}
246/**
247 * bu21013_gpio_irq() - gpio thread function for touch interrupt
248 * @irq: irq value
249 * @device_data: void pointer
250 *
251 * This gpio thread function for touch interrupt
252 * and returns irqreturn_t.
253 */
254static irqreturn_t bu21013_gpio_irq(int irq, void *device_data)
255{
256 struct bu21013_ts_data *data = device_data;
257 struct i2c_client *i2c = data->client;
258 int retval;
259
260 do {
261 retval = bu21013_do_touch_report(data);
262 if (retval < 0) {
263 dev_err(&i2c->dev, "bu21013_do_touch_report failed\n");
264 return IRQ_NONE;
265 }
266
Lee Jones31fbcda2012-09-28 10:29:07 +0100267 data->intr_pin = gpio_get_value(data->chip->touch_pin);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700268 if (data->intr_pin == PEN_DOWN_INTR)
269 wait_event_timeout(data->wait, data->touch_stopped,
270 msecs_to_jiffies(2));
271 } while (!data->intr_pin && !data->touch_stopped);
272
273 return IRQ_HANDLED;
274}
275
276/**
277 * bu21013_init_chip() - power on sequence for the bu21013 controller
278 * @data: device structure pointer
279 *
280 * This function is used to power on
281 * the bu21013 controller and returns integer.
282 */
283static int bu21013_init_chip(struct bu21013_ts_data *data)
284{
285 int retval;
286 struct i2c_client *i2c = data->client;
287
288 retval = i2c_smbus_write_byte_data(i2c, BU21013_RESET_REG,
289 BU21013_RESET_ENABLE);
290 if (retval < 0) {
291 dev_err(&i2c->dev, "BU21013_RESET reg write failed\n");
292 return retval;
293 }
294 msleep(RESET_DELAY);
295
296 retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_0_7_REG,
297 BU21013_SENSORS_EN_0_7);
298 if (retval < 0) {
299 dev_err(&i2c->dev, "BU21013_SENSOR_0_7 reg write failed\n");
300 return retval;
301 }
302
303 retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_8_15_REG,
304 BU21013_SENSORS_EN_8_15);
305 if (retval < 0) {
306 dev_err(&i2c->dev, "BU21013_SENSOR_8_15 reg write failed\n");
307 return retval;
308 }
309
310 retval = i2c_smbus_write_byte_data(i2c, BU21013_SENSOR_16_23_REG,
311 BU21013_SENSORS_EN_16_23);
312 if (retval < 0) {
313 dev_err(&i2c->dev, "BU21013_SENSOR_16_23 reg write failed\n");
314 return retval;
315 }
316
317 retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE1_REG,
318 (BU21013_POS_MODE1_0 | BU21013_POS_MODE1_1));
319 if (retval < 0) {
320 dev_err(&i2c->dev, "BU21013_POS_MODE1 reg write failed\n");
321 return retval;
322 }
323
324 retval = i2c_smbus_write_byte_data(i2c, BU21013_POS_MODE2_REG,
325 (BU21013_POS_MODE2_ZERO | BU21013_POS_MODE2_AVG1 |
326 BU21013_POS_MODE2_AVG2 | BU21013_POS_MODE2_EN_RAW |
327 BU21013_POS_MODE2_MULTI));
328 if (retval < 0) {
329 dev_err(&i2c->dev, "BU21013_POS_MODE2 reg write failed\n");
330 return retval;
331 }
332
333 if (data->chip->ext_clk)
334 retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG,
335 (BU21013_CLK_MODE_EXT | BU21013_CLK_MODE_CALIB));
336 else
337 retval = i2c_smbus_write_byte_data(i2c, BU21013_CLK_MODE_REG,
338 (BU21013_CLK_MODE_DIV | BU21013_CLK_MODE_CALIB));
339 if (retval < 0) {
340 dev_err(&i2c->dev, "BU21013_CLK_MODE reg write failed\n");
341 return retval;
342 }
343
344 retval = i2c_smbus_write_byte_data(i2c, BU21013_IDLE_REG,
345 (BU21013_IDLET_0 | BU21013_IDLE_INTERMIT_EN));
346 if (retval < 0) {
347 dev_err(&i2c->dev, "BU21013_IDLE reg write failed\n");
348 return retval;
349 }
350
351 retval = i2c_smbus_write_byte_data(i2c, BU21013_INT_MODE_REG,
352 BU21013_INT_MODE_LEVEL);
353 if (retval < 0) {
354 dev_err(&i2c->dev, "BU21013_INT_MODE reg write failed\n");
355 return retval;
356 }
357
358 retval = i2c_smbus_write_byte_data(i2c, BU21013_FILTER_REG,
359 (BU21013_DELTA_0_6 |
360 BU21013_FILTER_EN));
361 if (retval < 0) {
362 dev_err(&i2c->dev, "BU21013_FILTER reg write failed\n");
363 return retval;
364 }
365
366 retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_ON_REG,
367 BU21013_TH_ON_5);
368 if (retval < 0) {
369 dev_err(&i2c->dev, "BU21013_TH_ON reg write failed\n");
370 return retval;
371 }
372
373 retval = i2c_smbus_write_byte_data(i2c, BU21013_TH_OFF_REG,
David Sterbaef11e702010-12-27 17:20:01 -0800374 BU21013_TH_OFF_4 | BU21013_TH_OFF_3);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700375 if (retval < 0) {
376 dev_err(&i2c->dev, "BU21013_TH_OFF reg write failed\n");
377 return retval;
378 }
379
380 retval = i2c_smbus_write_byte_data(i2c, BU21013_GAIN_REG,
381 (BU21013_GAIN_0 | BU21013_GAIN_1));
382 if (retval < 0) {
383 dev_err(&i2c->dev, "BU21013_GAIN reg write failed\n");
384 return retval;
385 }
386
387 retval = i2c_smbus_write_byte_data(i2c, BU21013_OFFSET_MODE_REG,
388 BU21013_OFFSET_MODE_DEFAULT);
389 if (retval < 0) {
390 dev_err(&i2c->dev, "BU21013_OFFSET_MODE reg write failed\n");
391 return retval;
392 }
393
394 retval = i2c_smbus_write_byte_data(i2c, BU21013_XY_EDGE_REG,
395 (BU21013_X_EDGE_0 | BU21013_X_EDGE_2 |
396 BU21013_Y_EDGE_1 | BU21013_Y_EDGE_3));
397 if (retval < 0) {
398 dev_err(&i2c->dev, "BU21013_XY_EDGE reg write failed\n");
399 return retval;
400 }
401
402 retval = i2c_smbus_write_byte_data(i2c, BU21013_DONE_REG,
403 BU21013_DONE);
404 if (retval < 0) {
405 dev_err(&i2c->dev, "BU21013_REG_DONE reg write failed\n");
406 return retval;
407 }
408
409 return 0;
410}
411
412/**
413 * bu21013_free_irq() - frees IRQ registered for touchscreen
414 * @bu21013_data: device structure pointer
415 *
416 * This function signals interrupt thread to stop processing and
417 * frees interrupt.
418 */
419static void bu21013_free_irq(struct bu21013_ts_data *bu21013_data)
420{
421 bu21013_data->touch_stopped = true;
422 wake_up(&bu21013_data->wait);
Lee Jones31fbcda2012-09-28 10:29:07 +0100423 free_irq(bu21013_data->irq, bu21013_data);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700424}
425
426/**
Lee Jones31fbcda2012-09-28 10:29:07 +0100427 * bu21013_cs_disable() - deconfigures the touch panel controller
428 * @bu21013_data: device structure pointer
429 *
430 * This function is used to deconfigure the chip selection
431 * for touch panel controller.
432 */
433static void bu21013_cs_disable(struct bu21013_ts_data *bu21013_data)
434{
435 int error;
436
437 error = gpio_direction_output(bu21013_data->chip->cs_pin, 0);
438 if (error < 0)
439 dev_warn(&bu21013_data->client->dev,
440 "%s: gpio direction failed, error: %d\n",
441 __func__, error);
442 else
443 gpio_set_value(bu21013_data->chip->cs_pin, 0);
444
445 gpio_free(bu21013_data->chip->cs_pin);
446}
447
448
449/**
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700450 * bu21013_probe() - initializes the i2c-client touchscreen driver
451 * @client: i2c client structure pointer
452 * @id: i2c device id pointer
453 *
454 * This function used to initializes the i2c-client touchscreen
455 * driver and returns integer.
456 */
Bill Pemberton5298cc42012-11-23 21:38:25 -0800457static int bu21013_probe(struct i2c_client *client,
Lee Jones31fbcda2012-09-28 10:29:07 +0100458 const struct i2c_device_id *id)
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700459{
460 struct bu21013_ts_data *bu21013_data;
461 struct input_dev *in_dev;
462 const struct bu21013_platform_device *pdata =
463 client->dev.platform_data;
464 int error;
465
466 if (!i2c_check_functionality(client->adapter,
467 I2C_FUNC_SMBUS_BYTE_DATA)) {
468 dev_err(&client->dev, "i2c smbus byte data not supported\n");
469 return -EIO;
470 }
471
472 if (!pdata) {
473 dev_err(&client->dev, "platform data not defined\n");
474 return -EINVAL;
475 }
476
Lee Jones31fbcda2012-09-28 10:29:07 +0100477 if (!gpio_is_valid(pdata->touch_pin)) {
478 dev_err(&client->dev, "invalid touch_pin supplied\n");
479 return -EINVAL;
480 }
481
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700482 bu21013_data = kzalloc(sizeof(struct bu21013_ts_data), GFP_KERNEL);
483 in_dev = input_allocate_device();
484 if (!bu21013_data || !in_dev) {
485 dev_err(&client->dev, "device memory alloc failed\n");
486 error = -ENOMEM;
487 goto err_free_mem;
488 }
489
490 bu21013_data->in_dev = in_dev;
491 bu21013_data->chip = pdata;
492 bu21013_data->client = client;
Lee Jones31fbcda2012-09-28 10:29:07 +0100493 bu21013_data->irq = gpio_to_irq(pdata->touch_pin);
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800494
Lee Jones8c587f72012-11-21 19:11:46 -0800495 bu21013_data->regulator = regulator_get(&client->dev, "avdd");
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800496 if (IS_ERR(bu21013_data->regulator)) {
497 dev_err(&client->dev, "regulator_get failed\n");
498 error = PTR_ERR(bu21013_data->regulator);
499 goto err_free_mem;
500 }
501
502 error = regulator_enable(bu21013_data->regulator);
503 if (error < 0) {
504 dev_err(&client->dev, "regulator enable failed\n");
505 goto err_put_regulator;
506 }
507
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700508 bu21013_data->touch_stopped = false;
509 init_waitqueue_head(&bu21013_data->wait);
510
511 /* configure the gpio pins */
Lee Jones31fbcda2012-09-28 10:29:07 +0100512 error = gpio_request_one(pdata->cs_pin, GPIOF_OUT_INIT_HIGH,
513 "touchp_reset");
514 if (error < 0) {
515 dev_err(&client->dev, "Unable to request gpio reset_pin\n");
516 goto err_disable_regulator;
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700517 }
518
519 /* configure the touch panel controller */
520 error = bu21013_init_chip(bu21013_data);
521 if (error) {
522 dev_err(&client->dev, "error in bu21013 config\n");
523 goto err_cs_disable;
524 }
525
526 /* register the device to input subsystem */
527 in_dev->name = DRIVER_TP;
528 in_dev->id.bustype = BUS_I2C;
529 in_dev->dev.parent = &client->dev;
530
531 __set_bit(EV_SYN, in_dev->evbit);
532 __set_bit(EV_KEY, in_dev->evbit);
533 __set_bit(EV_ABS, in_dev->evbit);
534
535 input_set_abs_params(in_dev, ABS_MT_POSITION_X, 0,
Naveen Kumar Gaddipatid2763b42011-01-17 20:40:58 -0800536 pdata->touch_x_max, 0, 0);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700537 input_set_abs_params(in_dev, ABS_MT_POSITION_Y, 0,
Naveen Kumar Gaddipatid2763b42011-01-17 20:40:58 -0800538 pdata->touch_y_max, 0, 0);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700539 input_set_drvdata(in_dev, bu21013_data);
540
Lee Jones31fbcda2012-09-28 10:29:07 +0100541 error = request_threaded_irq(bu21013_data->irq, NULL, bu21013_gpio_irq,
Lars-Peter Clausen9b7e31b2012-07-04 13:02:56 -0700542 IRQF_TRIGGER_FALLING | IRQF_SHARED |
543 IRQF_ONESHOT,
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700544 DRIVER_TP, bu21013_data);
545 if (error) {
Lee Jones31fbcda2012-09-28 10:29:07 +0100546 dev_err(&client->dev, "request irq %d failed\n",
547 bu21013_data->irq);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700548 goto err_cs_disable;
549 }
550
551 error = input_register_device(in_dev);
552 if (error) {
553 dev_err(&client->dev, "failed to register input device\n");
554 goto err_free_irq;
555 }
556
557 device_init_wakeup(&client->dev, pdata->wakeup);
558 i2c_set_clientdata(client, bu21013_data);
559
560 return 0;
561
562err_free_irq:
563 bu21013_free_irq(bu21013_data);
564err_cs_disable:
Lee Jones31fbcda2012-09-28 10:29:07 +0100565 bu21013_cs_disable(bu21013_data);
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800566err_disable_regulator:
567 regulator_disable(bu21013_data->regulator);
568err_put_regulator:
569 regulator_put(bu21013_data->regulator);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700570err_free_mem:
Dan Carpenterbac64d02010-10-28 15:09:28 -0700571 input_free_device(in_dev);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700572 kfree(bu21013_data);
573
574 return error;
575}
576/**
577 * bu21013_remove() - removes the i2c-client touchscreen driver
578 * @client: i2c client structure pointer
579 *
580 * This function uses to remove the i2c-client
581 * touchscreen driver and returns integer.
582 */
Bill Pembertone2619cf2012-11-23 21:50:47 -0800583static int bu21013_remove(struct i2c_client *client)
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700584{
585 struct bu21013_ts_data *bu21013_data = i2c_get_clientdata(client);
586
587 bu21013_free_irq(bu21013_data);
588
Lee Jones31fbcda2012-09-28 10:29:07 +0100589 bu21013_cs_disable(bu21013_data);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700590
591 input_unregister_device(bu21013_data->in_dev);
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800592
593 regulator_disable(bu21013_data->regulator);
594 regulator_put(bu21013_data->regulator);
595
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700596 kfree(bu21013_data);
597
598 device_init_wakeup(&client->dev, false);
599
600 return 0;
601}
602
603#ifdef CONFIG_PM
604/**
605 * bu21013_suspend() - suspend the touch screen controller
606 * @dev: pointer to device structure
607 *
608 * This function is used to suspend the
609 * touch panel controller and returns integer
610 */
611static int bu21013_suspend(struct device *dev)
612{
613 struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev);
614 struct i2c_client *client = bu21013_data->client;
615
616 bu21013_data->touch_stopped = true;
617 if (device_may_wakeup(&client->dev))
Lee Jones31fbcda2012-09-28 10:29:07 +0100618 enable_irq_wake(bu21013_data->irq);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700619 else
Lee Jones31fbcda2012-09-28 10:29:07 +0100620 disable_irq(bu21013_data->irq);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700621
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800622 regulator_disable(bu21013_data->regulator);
623
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700624 return 0;
625}
626
627/**
628 * bu21013_resume() - resume the touch screen controller
629 * @dev: pointer to device structure
630 *
631 * This function is used to resume the touch panel
632 * controller and returns integer.
633 */
634static int bu21013_resume(struct device *dev)
635{
636 struct bu21013_ts_data *bu21013_data = dev_get_drvdata(dev);
637 struct i2c_client *client = bu21013_data->client;
638 int retval;
639
Naveen Kumar Gaddipati81e78de2011-01-17 20:47:31 -0800640 retval = regulator_enable(bu21013_data->regulator);
641 if (retval < 0) {
642 dev_err(&client->dev, "bu21013 regulator enable failed\n");
643 return retval;
644 }
645
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700646 retval = bu21013_init_chip(bu21013_data);
647 if (retval < 0) {
648 dev_err(&client->dev, "bu21013 controller config failed\n");
649 return retval;
650 }
651
652 bu21013_data->touch_stopped = false;
653
654 if (device_may_wakeup(&client->dev))
Lee Jones31fbcda2012-09-28 10:29:07 +0100655 disable_irq_wake(bu21013_data->irq);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700656 else
Lee Jones31fbcda2012-09-28 10:29:07 +0100657 enable_irq(bu21013_data->irq);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700658
659 return 0;
660}
661
662static const struct dev_pm_ops bu21013_dev_pm_ops = {
663 .suspend = bu21013_suspend,
664 .resume = bu21013_resume,
665};
666#endif
667
668static const struct i2c_device_id bu21013_id[] = {
669 { DRIVER_TP, 0 },
670 { }
671};
672MODULE_DEVICE_TABLE(i2c, bu21013_id);
673
674static struct i2c_driver bu21013_driver = {
675 .driver = {
676 .name = DRIVER_TP,
677 .owner = THIS_MODULE,
678#ifdef CONFIG_PM
679 .pm = &bu21013_dev_pm_ops,
680#endif
681 },
682 .probe = bu21013_probe,
Bill Pemberton1cb0aa82012-11-23 21:27:39 -0800683 .remove = bu21013_remove,
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700684 .id_table = bu21013_id,
685};
686
Axel Lin1b92c1c2012-03-16 23:05:41 -0700687module_i2c_driver(bu21013_driver);
Naveen Kumar Gaddipati4780c8d2010-10-04 22:32:48 -0700688
689MODULE_LICENSE("GPL v2");
690MODULE_AUTHOR("Naveen Kumar G <naveen.gaddipati@stericsson.com>");
691MODULE_DESCRIPTION("bu21013 touch screen controller driver");