PageRenderTime 86ms CodeModel.GetById 16ms app.highlight 63ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/arm/mach-msm/board-msm7627a-io.c

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