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