blob: 4df2232cca6d79dd63faf41db042ef19a9e7e2fe [file] [log] [blame]
Chintan Pandya0d453192012-03-09 13:20:33 +05301/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/platform_device.h>
15#include <linux/regulator/consumer.h>
16#include <linux/gpio_event.h>
17#include <linux/leds.h>
18#include <linux/i2c/atmel_mxt_ts.h>
19#include <linux/i2c.h>
20#include <linux/input/rmi_platformdata.h>
21#include <linux/input/rmi_i2c.h>
22#include <linux/delay.h>
23#include <linux/atmel_maxtouch.h>
24#include <linux/input/ft5x06_ts.h>
25#include <asm/gpio.h>
26#include <asm/mach-types.h>
27#include <mach/rpc_server_handset.h>
Mohan Pallaka6fbeb992012-04-18 15:37:28 +053028#include <mach/pmic.h>
Chintan Pandya0d453192012-03-09 13:20:33 +053029
30#include "devices.h"
31#include "board-msm7627a.h"
32#include "devices-msm7x2xa.h"
33
34#define ATMEL_TS_I2C_NAME "maXTouch"
35#define ATMEL_X_OFFSET 13
36#define ATMEL_Y_OFFSET 0
37
38#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C) || \
39defined(CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C_MODULE)
40
41#ifndef CLEARPAD3000_ATTEN_GPIO
42#define CLEARPAD3000_ATTEN_GPIO (48)
43#endif
44
45#ifndef CLEARPAD3000_RESET_GPIO
46#define CLEARPAD3000_RESET_GPIO (26)
47#endif
48
49#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))
50
51static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
52static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
53
54static const unsigned short keymap[ARRAY_SIZE(kp_col_gpios) *
55 ARRAY_SIZE(kp_row_gpios)] = {
56 [KP_INDEX(0, 0)] = KEY_7,
57 [KP_INDEX(0, 1)] = KEY_DOWN,
58 [KP_INDEX(0, 2)] = KEY_UP,
59 [KP_INDEX(0, 3)] = KEY_RIGHT,
60 [KP_INDEX(0, 4)] = KEY_ENTER,
61
62 [KP_INDEX(1, 0)] = KEY_LEFT,
63 [KP_INDEX(1, 1)] = KEY_SEND,
64 [KP_INDEX(1, 2)] = KEY_1,
65 [KP_INDEX(1, 3)] = KEY_4,
66 [KP_INDEX(1, 4)] = KEY_CLEAR,
67
68 [KP_INDEX(2, 0)] = KEY_6,
69 [KP_INDEX(2, 1)] = KEY_5,
70 [KP_INDEX(2, 2)] = KEY_8,
71 [KP_INDEX(2, 3)] = KEY_3,
72 [KP_INDEX(2, 4)] = KEY_NUMERIC_STAR,
73
74 [KP_INDEX(3, 0)] = KEY_9,
75 [KP_INDEX(3, 1)] = KEY_NUMERIC_POUND,
76 [KP_INDEX(3, 2)] = KEY_0,
77 [KP_INDEX(3, 3)] = KEY_2,
78 [KP_INDEX(3, 4)] = KEY_SLEEP,
79
80 [KP_INDEX(4, 0)] = KEY_BACK,
81 [KP_INDEX(4, 1)] = KEY_HOME,
82 [KP_INDEX(4, 2)] = KEY_MENU,
83 [KP_INDEX(4, 3)] = KEY_VOLUMEUP,
84 [KP_INDEX(4, 4)] = KEY_VOLUMEDOWN,
85};
86
87/* SURF keypad platform device information */
88static struct gpio_event_matrix_info kp_matrix_info = {
89 .info.func = gpio_event_matrix_func,
90 .keymap = keymap,
91 .output_gpios = kp_row_gpios,
92 .input_gpios = kp_col_gpios,
93 .noutputs = ARRAY_SIZE(kp_row_gpios),
94 .ninputs = ARRAY_SIZE(kp_col_gpios),
95 .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
96 .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
97 .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
98 GPIOKPF_PRINT_UNMAPPED_KEYS,
99};
100
101static struct gpio_event_info *kp_info[] = {
102 &kp_matrix_info.info
103};
104
105static struct gpio_event_platform_data kp_pdata = {
106 .name = "7x27a_kp",
107 .info = kp_info,
108 .info_count = ARRAY_SIZE(kp_info)
109};
110
111static struct platform_device kp_pdev = {
112 .name = GPIO_EVENT_DEV_NAME,
113 .id = -1,
114 .dev = {
115 .platform_data = &kp_pdata,
116 },
117};
118
119/* 8625 keypad device information */
120static unsigned int kp_row_gpios_8625[] = {31};
121static unsigned int kp_col_gpios_8625[] = {36, 37};
122
123static const unsigned short keymap_8625[] = {
124 KEY_VOLUMEUP,
125 KEY_VOLUMEDOWN,
126};
127
128static struct gpio_event_matrix_info kp_matrix_info_8625 = {
129 .info.func = gpio_event_matrix_func,
130 .keymap = keymap_8625,
131 .output_gpios = kp_row_gpios_8625,
132 .input_gpios = kp_col_gpios_8625,
133 .noutputs = ARRAY_SIZE(kp_row_gpios_8625),
134 .ninputs = ARRAY_SIZE(kp_col_gpios_8625),
135 .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
136 .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
137 .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
138 GPIOKPF_PRINT_UNMAPPED_KEYS,
139};
140
141static struct gpio_event_info *kp_info_8625[] = {
142 &kp_matrix_info_8625.info,
143};
144
145static struct gpio_event_platform_data kp_pdata_8625 = {
Mohan Pallaka719aaa92012-04-03 12:21:03 +0530146 .name = "7x27a_kp",
Chintan Pandya0d453192012-03-09 13:20:33 +0530147 .info = kp_info_8625,
148 .info_count = ARRAY_SIZE(kp_info_8625)
149};
150
151static struct platform_device kp_pdev_8625 = {
152 .name = GPIO_EVENT_DEV_NAME,
153 .id = -1,
154 .dev = {
155 .platform_data = &kp_pdata_8625,
156 },
157};
158
159#define LED_GPIO_PDM 96
160#define LED_RED_GPIO_8625 49
161#define LED_GREEN_GPIO_8625 34
162
163static struct gpio_led gpio_leds_config_8625[] = {
164 {
165 .name = "green",
166 .gpio = LED_GREEN_GPIO_8625,
167 },
168 {
169 .name = "red",
170 .gpio = LED_RED_GPIO_8625,
171 },
172};
173
174static struct gpio_led_platform_data gpio_leds_pdata_8625 = {
175 .num_leds = ARRAY_SIZE(gpio_leds_config_8625),
176 .leds = gpio_leds_config_8625,
177};
178
179static struct platform_device gpio_leds_8625 = {
180 .name = "leds-gpio",
181 .id = -1,
182 .dev = {
183 .platform_data = &gpio_leds_pdata_8625,
184 },
185};
186
187#define MXT_TS_IRQ_GPIO 48
188#define MXT_TS_RESET_GPIO 26
189
190static const u8 mxt_config_data[] = {
191 /* T6 Object */
192 0, 0, 0, 0, 0, 0,
193 /* T38 Object */
194 16, 0, 0, 0, 0, 0, 0, 0,
195 /* T7 Object */
196 32, 16, 50,
197 /* T8 Object */
198 30, 0, 20, 20, 0, 0, 20, 0, 50, 0,
199 /* T9 Object */
200 3, 0, 0, 18, 11, 0, 32, 75, 3, 3,
201 0, 1, 1, 0, 10, 10, 10, 10, 31, 3,
202 223, 1, 11, 11, 15, 15, 151, 43, 145, 80,
203 100, 15, 0, 0, 0,
204 /* T15 Object */
205 131, 0, 11, 11, 1, 1, 0, 45, 3, 0,
206 0,
207 /* T18 Object */
208 0, 0,
209 /* T19 Object */
210 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
211 0, 0, 0, 0, 0, 0,
212 /* T23 Object */
213 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
214 0, 0, 0, 0, 0,
215 /* T25 Object */
216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
217 0, 0, 0, 0,
218 /* T40 Object */
219 0, 0, 0, 0, 0,
220 /* T42 Object */
221 0, 0, 0, 0, 0, 0, 0, 0,
222 /* T46 Object */
223 0, 2, 32, 48, 0, 0, 0, 0, 0,
224 /* T47 Object */
225 1, 20, 60, 5, 2, 50, 40, 0, 0, 40,
226 /* T48 Object */
227 1, 12, 80, 0, 0, 0, 0, 0, 0, 0,
228 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
229 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
230 0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
231 10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
232 80, 100, 15, 3,
233};
234
235static struct mxt_config_info mxt_config_array[] = {
236 {
237 .config = mxt_config_data,
238 .config_length = ARRAY_SIZE(mxt_config_data),
239 .family_id = 0x81,
240 .variant_id = 0x01,
241 .version = 0x10,
242 .build = 0xAA,
243 },
244};
245
246static int mxt_key_codes[MXT_KEYARRAY_MAX_KEYS] = {
247 [0] = KEY_HOME,
248 [1] = KEY_MENU,
249 [9] = KEY_BACK,
250 [10] = KEY_SEARCH,
251};
252
253static struct mxt_platform_data mxt_platform_data = {
254 .config_array = mxt_config_array,
255 .config_array_size = ARRAY_SIZE(mxt_config_array),
256 .panel_minx = 0,
257 .panel_maxx = 479,
258 .panel_miny = 0,
259 .panel_maxy = 799,
260 .disp_minx = 0,
261 .disp_maxx = 479,
262 .disp_miny = 0,
263 .disp_maxy = 799,
264 .irqflags = IRQF_TRIGGER_FALLING,
265 .i2c_pull_up = true,
266 .reset_gpio = MXT_TS_RESET_GPIO,
267 .irq_gpio = MXT_TS_IRQ_GPIO,
268 .key_codes = mxt_key_codes,
269};
270
271static struct i2c_board_info mxt_device_info[] __initdata = {
272 {
273 I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
274 .platform_data = &mxt_platform_data,
275 .irq = MSM_GPIO_TO_INT(MXT_TS_IRQ_GPIO),
276 },
277};
278
279static int synaptics_touchpad_setup(void);
280
281static struct msm_gpio clearpad3000_cfg_data[] = {
282 {GPIO_CFG(CLEARPAD3000_ATTEN_GPIO, 0, GPIO_CFG_INPUT,
283 GPIO_CFG_NO_PULL, GPIO_CFG_6MA), "rmi4_attn"},
284 {GPIO_CFG(CLEARPAD3000_RESET_GPIO, 0, GPIO_CFG_OUTPUT,
285 GPIO_CFG_PULL_DOWN, GPIO_CFG_8MA), "rmi4_reset"},
286};
287
288static struct rmi_XY_pair rmi_offset = {.x = 0, .y = 0};
289static struct rmi_range rmi_clipx = {.min = 48, .max = 980};
290static struct rmi_range rmi_clipy = {.min = 7, .max = 1647};
291static struct rmi_f11_functiondata synaptics_f11_data = {
292 .swap_axes = false,
293 .flipX = false,
294 .flipY = false,
295 .offset = &rmi_offset,
296 .button_height = 113,
297 .clipX = &rmi_clipx,
298 .clipY = &rmi_clipy,
299};
300
301#define MAX_LEN 100
302
303static ssize_t clearpad3000_virtual_keys_register(struct kobject *kobj,
304 struct kobj_attribute *attr, char *buf)
305{
306 char *virtual_keys = __stringify(EV_KEY) ":" __stringify(KEY_MENU) \
307 ":60:830:120:60" ":" __stringify(EV_KEY) \
308 ":" __stringify(KEY_HOME) ":180:830:120:60" \
309 ":" __stringify(EV_KEY) ":" \
310 __stringify(KEY_SEARCH) ":300:830:120:60" \
311 ":" __stringify(EV_KEY) ":" \
312 __stringify(KEY_BACK) ":420:830:120:60" "\n";
313
314 return snprintf(buf, strnlen(virtual_keys, MAX_LEN) + 1 , "%s",
315 virtual_keys);
316}
317
318static struct kobj_attribute clearpad3000_virtual_keys_attr = {
319 .attr = {
320 .name = "virtualkeys.sensor00fn11",
321 .mode = S_IRUGO,
322 },
323 .show = &clearpad3000_virtual_keys_register,
324};
325
326static struct attribute *virtual_key_properties_attrs[] = {
327 &clearpad3000_virtual_keys_attr.attr,
328 NULL
329};
330
331static struct attribute_group virtual_key_properties_attr_group = {
332 .attrs = virtual_key_properties_attrs,
333};
334
335struct kobject *virtual_key_properties_kobj;
336
337static struct rmi_functiondata synaptics_functiondata[] = {
338 {
339 .function_index = RMI_F11_INDEX,
340 .data = &synaptics_f11_data,
341 },
342};
343
344static struct rmi_functiondata_list synaptics_perfunctiondata = {
345 .count = ARRAY_SIZE(synaptics_functiondata),
346 .functiondata = synaptics_functiondata,
347};
348
349static struct rmi_sensordata synaptics_sensordata = {
350 .perfunctiondata = &synaptics_perfunctiondata,
351 .rmi_sensor_setup = synaptics_touchpad_setup,
352};
353
354static struct rmi_i2c_platformdata synaptics_platformdata = {
355 .i2c_address = 0x2c,
356 .irq_type = IORESOURCE_IRQ_LOWLEVEL,
357 .sensordata = &synaptics_sensordata,
358};
359
360static struct i2c_board_info synaptic_i2c_clearpad3k[] = {
361 {
362 I2C_BOARD_INFO("rmi4_ts", 0x2c),
363 .platform_data = &synaptics_platformdata,
364 },
365};
366
367static int synaptics_touchpad_setup(void)
368{
369 int retval = 0;
370
371 virtual_key_properties_kobj =
372 kobject_create_and_add("board_properties", NULL);
373 if (virtual_key_properties_kobj)
374 retval = sysfs_create_group(virtual_key_properties_kobj,
375 &virtual_key_properties_attr_group);
376 if (!virtual_key_properties_kobj || retval)
377 pr_err("failed to create ft5202 board_properties\n");
378
379 retval = msm_gpios_request_enable(clearpad3000_cfg_data,
380 sizeof(clearpad3000_cfg_data)/sizeof(struct msm_gpio));
381 if (retval) {
382 pr_err("%s:Failed to obtain touchpad GPIO %d. Code: %d.",
383 __func__, CLEARPAD3000_ATTEN_GPIO, retval);
384 retval = 0; /* ignore the err */
385 }
386 synaptics_platformdata.irq = gpio_to_irq(CLEARPAD3000_ATTEN_GPIO);
387
388 gpio_set_value(CLEARPAD3000_RESET_GPIO, 0);
389 usleep(10000);
390 gpio_set_value(CLEARPAD3000_RESET_GPIO, 1);
391 usleep(50000);
392
393 return retval;
394}
395#endif
396
397static struct regulator_bulk_data regs_atmel[] = {
Mohan Pallakaaf51bb12012-04-26 15:51:30 +0530398 { .supply = "ldo12", .min_uV = 2700000, .max_uV = 3300000 },
Chintan Pandya0d453192012-03-09 13:20:33 +0530399 { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
400};
401
402#define ATMEL_TS_GPIO_IRQ 82
403
404static int atmel_ts_power_on(bool on)
405{
406 int rc = on ?
407 regulator_bulk_enable(ARRAY_SIZE(regs_atmel), regs_atmel) :
408 regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
409
410 if (rc)
411 pr_err("%s: could not %sable regulators: %d\n",
412 __func__, on ? "en" : "dis", rc);
413 else
414 msleep(50);
415
416 return rc;
417}
418
419static int atmel_ts_platform_init(struct i2c_client *client)
420{
421 int rc;
422 struct device *dev = &client->dev;
423
424 rc = regulator_bulk_get(dev, ARRAY_SIZE(regs_atmel), regs_atmel);
425 if (rc) {
426 dev_err(dev, "%s: could not get regulators: %d\n",
427 __func__, rc);
428 goto out;
429 }
430
431 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_atmel), regs_atmel);
432 if (rc) {
433 dev_err(dev, "%s: could not set voltages: %d\n",
434 __func__, rc);
435 goto reg_free;
436 }
437
438 rc = gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
439 GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
440 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
441 if (rc) {
442 dev_err(dev, "%s: gpio_tlmm_config for %d failed\n",
443 __func__, ATMEL_TS_GPIO_IRQ);
444 goto reg_free;
445 }
446
447 /* configure touchscreen interrupt gpio */
448 rc = gpio_request(ATMEL_TS_GPIO_IRQ, "atmel_maxtouch_gpio");
449 if (rc) {
450 dev_err(dev, "%s: unable to request gpio %d\n",
451 __func__, ATMEL_TS_GPIO_IRQ);
452 goto ts_gpio_tlmm_unconfig;
453 }
454
455 rc = gpio_direction_input(ATMEL_TS_GPIO_IRQ);
456 if (rc < 0) {
457 dev_err(dev, "%s: unable to set the direction of gpio %d\n",
458 __func__, ATMEL_TS_GPIO_IRQ);
459 goto free_ts_gpio;
460 }
461 return 0;
462
463free_ts_gpio:
464 gpio_free(ATMEL_TS_GPIO_IRQ);
465ts_gpio_tlmm_unconfig:
466 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
467 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
468 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
469reg_free:
470 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
471out:
472 return rc;
473}
474
475static int atmel_ts_platform_exit(struct i2c_client *client)
476{
477 gpio_free(ATMEL_TS_GPIO_IRQ);
478 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
479 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
480 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
481 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
482 return 0;
483}
484
485static u8 atmel_ts_read_chg(void)
486{
487 return gpio_get_value(ATMEL_TS_GPIO_IRQ);
488}
489
490static u8 atmel_ts_valid_interrupt(void)
491{
492 return !atmel_ts_read_chg();
493}
494
495
496static struct maxtouch_platform_data atmel_ts_pdata = {
497 .numtouch = 4,
498 .init_platform_hw = atmel_ts_platform_init,
499 .exit_platform_hw = atmel_ts_platform_exit,
500 .power_on = atmel_ts_power_on,
501 .display_res_x = 480,
502 .display_res_y = 864,
503 .min_x = ATMEL_X_OFFSET,
504 .max_x = (505 - ATMEL_X_OFFSET),
505 .min_y = ATMEL_Y_OFFSET,
506 .max_y = (863 - ATMEL_Y_OFFSET),
507 .valid_interrupt = atmel_ts_valid_interrupt,
508 .read_chg = atmel_ts_read_chg,
509};
510
511static struct i2c_board_info atmel_ts_i2c_info[] __initdata = {
512 {
513 I2C_BOARD_INFO(ATMEL_TS_I2C_NAME, 0x4a),
514 .platform_data = &atmel_ts_pdata,
515 .irq = MSM_GPIO_TO_INT(ATMEL_TS_GPIO_IRQ),
516 },
517};
518
519static struct msm_handset_platform_data hs_platform_data = {
520 .hs_name = "7k_handset",
521 .pwr_key_delay_ms = 500, /* 0 will disable end key */
522};
523
524static struct platform_device hs_pdev = {
525 .name = "msm-handset",
526 .id = -1,
527 .dev = {
528 .platform_data = &hs_platform_data,
529 },
530};
531
532#define FT5X06_IRQ_GPIO 48
533#define FT5X06_RESET_GPIO 26
534
535static ssize_t
536ft5x06_virtual_keys_register(struct kobject *kobj,
537 struct kobj_attribute *attr,
538 char *buf)
539{
540 return snprintf(buf, 200,
541 __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":40:510:80:60"
542 ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":120:510:80:60"
543 ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
544 ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":280:510:80:60"
545 "\n");
546}
547
548static struct kobj_attribute ft5x06_virtual_keys_attr = {
549 .attr = {
550 .name = "virtualkeys.ft5x06_ts",
551 .mode = S_IRUGO,
552 },
553 .show = &ft5x06_virtual_keys_register,
554};
555
556static struct attribute *ft5x06_virtual_key_properties_attrs[] = {
557 &ft5x06_virtual_keys_attr.attr,
558 NULL,
559};
560
561static struct attribute_group ft5x06_virtual_key_properties_attr_group = {
562 .attrs = ft5x06_virtual_key_properties_attrs,
563};
564
565struct kobject *ft5x06_virtual_key_properties_kobj;
566
567static struct ft5x06_ts_platform_data ft5x06_platformdata = {
568 .x_max = 320,
569 .y_max = 480,
570 .reset_gpio = FT5X06_RESET_GPIO,
571 .irq_gpio = FT5X06_IRQ_GPIO,
572 .irqflags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
573};
574
575static struct i2c_board_info ft5x06_device_info[] __initdata = {
576 {
577 I2C_BOARD_INFO("ft5x06_ts", 0x38),
578 .platform_data = &ft5x06_platformdata,
579 .irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO),
580 },
581};
582
Stephen Boyd668d7652012-04-25 11:31:01 -0700583static void __init ft5x06_touchpad_setup(void)
Chintan Pandya0d453192012-03-09 13:20:33 +0530584{
585 int rc;
586
587 rc = gpio_tlmm_config(GPIO_CFG(FT5X06_IRQ_GPIO, 0,
588 GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
589 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
590 if (rc)
591 pr_err("%s: gpio_tlmm_config for %d failed\n",
592 __func__, FT5X06_IRQ_GPIO);
593
594 rc = gpio_tlmm_config(GPIO_CFG(FT5X06_RESET_GPIO, 0,
595 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
596 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
597 if (rc)
598 pr_err("%s: gpio_tlmm_config for %d failed\n",
599 __func__, FT5X06_RESET_GPIO);
600
601 ft5x06_virtual_key_properties_kobj =
602 kobject_create_and_add("board_properties", NULL);
603
604 if (ft5x06_virtual_key_properties_kobj)
605 rc = sysfs_create_group(ft5x06_virtual_key_properties_kobj,
606 &ft5x06_virtual_key_properties_attr_group);
607
608 if (!ft5x06_virtual_key_properties_kobj || rc)
609 pr_err("%s: failed to create board_properties\n", __func__);
610
611 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
612 ft5x06_device_info,
613 ARRAY_SIZE(ft5x06_device_info));
614}
615
Mohan Pallaka719aaa92012-04-03 12:21:03 +0530616/* SKU3/SKU7 keypad device information */
617#define KP_INDEX_SKU3(row, col) ((row)*ARRAY_SIZE(kp_col_gpios_sku3) + (col))
618static unsigned int kp_row_gpios_sku3[] = {31, 32};
619static unsigned int kp_col_gpios_sku3[] = {36, 37};
620
621static const unsigned short keymap_sku3[] = {
622 [KP_INDEX_SKU3(0, 0)] = KEY_VOLUMEUP,
623 [KP_INDEX_SKU3(0, 1)] = KEY_VOLUMEDOWN,
624 [KP_INDEX_SKU3(1, 1)] = KEY_CAMERA,
625};
626
627static struct gpio_event_matrix_info kp_matrix_info_sku3 = {
628 .info.func = gpio_event_matrix_func,
629 .keymap = keymap_sku3,
630 .output_gpios = kp_row_gpios_sku3,
631 .input_gpios = kp_col_gpios_sku3,
632 .noutputs = ARRAY_SIZE(kp_row_gpios_sku3),
633 .ninputs = ARRAY_SIZE(kp_col_gpios_sku3),
634 .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
635 .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
636 .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
637 GPIOKPF_PRINT_UNMAPPED_KEYS,
638};
639
640static struct gpio_event_info *kp_info_sku3[] = {
641 &kp_matrix_info_sku3.info,
642};
643static struct gpio_event_platform_data kp_pdata_sku3 = {
644 .name = "7x27a_kp",
645 .info = kp_info_sku3,
646 .info_count = ARRAY_SIZE(kp_info_sku3)
647};
648
649static struct platform_device kp_pdev_sku3 = {
650 .name = GPIO_EVENT_DEV_NAME,
651 .id = -1,
652 .dev = {
653 .platform_data = &kp_pdata_sku3,
654 },
655};
656
Mohan Pallaka6fbeb992012-04-18 15:37:28 +0530657static struct led_info ctp_backlight_info = {
658 .name = "button-backlight",
659 .flags = PM_MPP__I_SINK__LEVEL_40mA << 16 | PM_MPP_7,
660};
661
662static struct led_platform_data ctp_backlight_pdata = {
663 .leds = &ctp_backlight_info,
664 .num_leds = 1,
665};
666
667static struct platform_device pmic_mpp_leds_pdev = {
668 .name = "pmic-mpp-leds",
669 .id = -1,
670 .dev = {
671 .platform_data = &ctp_backlight_pdata,
672 },
673};
674
Chintan Pandya0d453192012-03-09 13:20:33 +0530675void __init msm7627a_add_io_devices(void)
676{
677 /* touchscreen */
678 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
679 atmel_ts_pdata.min_x = 0;
680 atmel_ts_pdata.max_x = 480;
681 atmel_ts_pdata.min_y = 0;
682 atmel_ts_pdata.max_y = 320;
683 }
684
685 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
686 atmel_ts_i2c_info,
687 ARRAY_SIZE(atmel_ts_i2c_info));
688 /* keypad */
689 platform_device_register(&kp_pdev);
690
691 /* headset */
692 platform_device_register(&hs_pdev);
693
694 /* LED: configure it as a pdm function */
695 if (gpio_tlmm_config(GPIO_CFG(LED_GPIO_PDM, 3,
696 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
697 GPIO_CFG_8MA), GPIO_CFG_ENABLE))
698 pr_err("%s: gpio_tlmm_config for %d failed\n",
699 __func__, LED_GPIO_PDM);
700 else
701 platform_device_register(&led_pdev);
702
703 /* Vibrator */
Aparna Mallavarapu9f000a72012-04-20 15:37:57 +0530704 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
705 || machine_is_msm8625_ffa())
Chintan Pandya0d453192012-03-09 13:20:33 +0530706 msm_init_pmic_vibrator();
707}
708
709void __init qrd7627a_add_io_devices(void)
710{
711 int rc;
712
713 /* touchscreen */
714 if (machine_is_msm7627a_qrd1()) {
715 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
716 synaptic_i2c_clearpad3k,
717 ARRAY_SIZE(synaptic_i2c_clearpad3k));
718 } else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
719 rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
720 GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
721 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
722 if (rc) {
723 pr_err("%s: gpio_tlmm_config for %d failed\n",
724 __func__, MXT_TS_IRQ_GPIO);
725 }
726
727 rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_RESET_GPIO, 0,
728 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
729 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
730 if (rc) {
731 pr_err("%s: gpio_tlmm_config for %d failed\n",
732 __func__, MXT_TS_RESET_GPIO);
733 }
734
735 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
736 mxt_device_info,
737 ARRAY_SIZE(mxt_device_info));
Mohan Pallaka4e5964b2012-04-03 12:22:19 +0530738 } else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
Chintan Pandya0d453192012-03-09 13:20:33 +0530739 ft5x06_touchpad_setup();
740 }
741
742 /* headset */
743 platform_device_register(&hs_pdev);
744
745 /* vibrator */
746#ifdef CONFIG_MSM_RPC_VIBRATOR
747 msm_init_pmic_vibrator();
748#endif
749
750 /* keypad */
751 if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
752 platform_device_register(&kp_pdev_8625);
Mohan Pallaka719aaa92012-04-03 12:21:03 +0530753 else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
754 platform_device_register(&kp_pdev_sku3);
Chintan Pandya0d453192012-03-09 13:20:33 +0530755
756 /* leds */
757 if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
758 rc = gpio_tlmm_config(GPIO_CFG(LED_RED_GPIO_8625, 0,
759 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
760 GPIO_CFG_16MA), GPIO_CFG_ENABLE);
761 if (rc) {
762 pr_err("%s: gpio_tlmm_config for %d failed\n",
763 __func__, LED_RED_GPIO_8625);
764 }
765
766 rc = gpio_tlmm_config(GPIO_CFG(LED_GREEN_GPIO_8625, 0,
767 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
768 GPIO_CFG_16MA), GPIO_CFG_ENABLE);
769 if (rc) {
770 pr_err("%s: gpio_tlmm_config for %d failed\n",
771 __func__, LED_GREEN_GPIO_8625);
772 }
773
774 platform_device_register(&gpio_leds_8625);
Mohan Pallaka6fbeb992012-04-18 15:37:28 +0530775 platform_device_register(&pmic_mpp_leds_pdev);
Chintan Pandya0d453192012-03-09 13:20:33 +0530776 }
777}