blob: f51c61d6e156a8983a876c4e779002d0899196c0 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2011, 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#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/gpio_event.h>
15#include <asm/mach-types.h>
16#include <asm/mach/arch.h>
17#include <mach/board.h>
18#include <mach/msm_iomap.h>
19#include <mach/msm_hsusb.h>
20#include <mach/rpc_hsusb.h>
21#include <mach/rpc_pmapp.h>
22#include <mach/usbdiag.h>
23#include <mach/msm_memtypes.h>
24#include <mach/msm_serial_hs.h>
25#include <linux/usb/android.h>
26#include <linux/platform_device.h>
27#include <linux/io.h>
28#include <linux/gpio.h>
29#include <mach/vreg.h>
30#include <mach/pmic.h>
31#include <mach/socinfo.h>
32#include <linux/mtd/nand.h>
33#include <linux/mtd/partitions.h>
34#include <asm/mach/mmc.h>
35#include <linux/i2c.h>
36#include <linux/i2c/sx150x.h>
37#include <linux/gpio.h>
38#include <linux/android_pmem.h>
39#include <linux/bootmem.h>
40#include <linux/mfd/marimba.h>
41#include <mach/vreg.h>
42#include <linux/power_supply.h>
Justin Paupored98328e2011-08-19 13:48:31 -070043#include <linux/regulator/consumer.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070044#include <mach/rpc_pmapp.h>
45
46#include <mach/msm_battery.h>
47#include <linux/smsc911x.h>
48#include <linux/atmel_maxtouch.h>
49#include "devices.h"
50#include "timer.h"
Justin Pauporeb3a33b72011-08-23 15:30:32 -070051#include "board-msm7x27a-regulator.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070052#include "devices-msm7x2xa.h"
53#include "pm.h"
54#include <mach/rpc_server_handset.h>
55#include <mach/socinfo.h>
56
57#define PMEM_KERNEL_EBI1_SIZE 0x3A000
58#define MSM_PMEM_AUDIO_SIZE 0x5B000
59#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
60#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
Rahul Kashyap181d5552011-07-07 10:39:23 +053061#define BAHAMA_SLAVE_ID_FM_REG 0x02
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062#define FM_GPIO 83
63
64enum {
65 GPIO_EXPANDER_IRQ_BASE = NR_MSM_IRQS + NR_GPIO_IRQS,
66 GPIO_EXPANDER_GPIO_BASE = NR_MSM_GPIOS,
67 /* SURF expander */
68 GPIO_CORE_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
69 GPIO_BT_SYS_REST_EN = GPIO_CORE_EXPANDER_BASE,
70 GPIO_WLAN_EXT_POR_N,
71 GPIO_DISPLAY_PWR_EN,
72 GPIO_BACKLIGHT_EN,
73 GPIO_PRESSURE_XCLR,
74 GPIO_VREG_S3_EXP,
75 GPIO_UBM2M_PWRDWN,
76 GPIO_ETM_MODE_CS_N,
77 GPIO_HOST_VBUS_EN,
78 GPIO_SPI_MOSI,
79 GPIO_SPI_MISO,
80 GPIO_SPI_CLK,
81 GPIO_SPI_CS0_N,
82 GPIO_CORE_EXPANDER_IO13,
83 GPIO_CORE_EXPANDER_IO14,
84 GPIO_CORE_EXPANDER_IO15,
85 /* Camera expander */
86 GPIO_CAM_EXPANDER_BASE = GPIO_CORE_EXPANDER_BASE + 16,
87 GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
88 GPIO_CAM_GP_AFBUSY,
89 GPIO_CAM_GP_CAM_PWDN,
90 GPIO_CAM_GP_CAM1MP_XCLR,
91 GPIO_CAM_GP_CAMIF_RESET_N,
92 GPIO_CAM_GP_STROBE_CE,
93 GPIO_CAM_GP_LED_EN1,
94 GPIO_CAM_GP_LED_EN2,
95};
96
97#if defined(CONFIG_GPIO_SX150X)
98enum {
99 SX150X_CORE,
100 SX150X_CAM,
101};
102
103static struct sx150x_platform_data sx150x_data[] __initdata = {
104 [SX150X_CORE] = {
105 .gpio_base = GPIO_CORE_EXPANDER_BASE,
106 .oscio_is_gpo = false,
107 .io_pullup_ena = 0,
pankaj kumarc5c01392011-08-12 13:44:05 +0530108 .io_pulldn_ena = 0x02,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700109 .io_open_drain_ena = 0xfef8,
110 .irq_summary = -1,
111 },
112 [SX150X_CAM] = {
113 .gpio_base = GPIO_CAM_EXPANDER_BASE,
114 .oscio_is_gpo = false,
115 .io_pullup_ena = 0,
116 .io_pulldn_ena = 0,
117 .io_open_drain_ena = 0x23,
118 .irq_summary = -1,
119 },
120};
121#endif
122
123#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
124
125 /* FM Platform power and shutdown routines */
126#define FPGA_MSM_CNTRL_REG2 0x90008010
Rahul Kashyap6e669462011-07-23 16:42:56 +0530127
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700128static void config_pcm_i2s_mode(int mode)
129{
130 void __iomem *cfg_ptr;
131 u8 reg2;
132
133 cfg_ptr = ioremap_nocache(FPGA_MSM_CNTRL_REG2, sizeof(char));
134
135 if (!cfg_ptr)
136 return;
137 if (mode) {
138 /*enable the pcm mode in FPGA*/
139 reg2 = readb_relaxed(cfg_ptr);
140 if (reg2 == 0) {
141 reg2 = 1;
142 writeb_relaxed(reg2, cfg_ptr);
143 }
144 } else {
145 /*enable i2s mode in FPGA*/
146 reg2 = readb_relaxed(cfg_ptr);
147 if (reg2 == 1) {
148 reg2 = 0;
149 writeb_relaxed(reg2, cfg_ptr);
150 }
151 }
152 iounmap(cfg_ptr);
153}
154
155static unsigned fm_i2s_config_power_on[] = {
156 /*FM_I2S_SD*/
157 GPIO_CFG(68, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
158 /*FM_I2S_WS*/
159 GPIO_CFG(70, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
160 /*FM_I2S_SCK*/
161 GPIO_CFG(71, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
162};
163
164static unsigned fm_i2s_config_power_off[] = {
165 /*FM_I2S_SD*/
166 GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
167 /*FM_I2S_WS*/
168 GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
169 /*FM_I2S_SCK*/
170 GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
171};
172
173static unsigned bt_config_power_on[] = {
174 /*RFR*/
175 GPIO_CFG(43, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
176 /*CTS*/
177 GPIO_CFG(44, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
178 /*RX*/
179 GPIO_CFG(45, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
180 /*TX*/
181 GPIO_CFG(46, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
182};
183static unsigned bt_config_pcm_on[] = {
184 /*PCM_DOUT*/
185 GPIO_CFG(68, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
186 /*PCM_DIN*/
187 GPIO_CFG(69, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
188 /*PCM_SYNC*/
189 GPIO_CFG(70, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
190 /*PCM_CLK*/
191 GPIO_CFG(71, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
192};
193static unsigned bt_config_power_off[] = {
194 /*RFR*/
195 GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
196 /*CTS*/
197 GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
198 /*RX*/
199 GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
200 /*TX*/
201 GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
202};
203static unsigned bt_config_pcm_off[] = {
204 /*PCM_DOUT*/
205 GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
206 /*PCM_DIN*/
207 GPIO_CFG(69, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
208 /*PCM_SYNC*/
209 GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
210 /*PCM_CLK*/
211 GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
212};
213
214static int config_i2s(int mode)
215{
216 int pin, rc = 0;
217
218 if (mode == FM_I2S_ON) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +0530219 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700220 config_pcm_i2s_mode(0);
221 pr_err("%s mode = FM_I2S_ON", __func__);
222 for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_on);
223 pin++) {
224 rc = gpio_tlmm_config(
225 fm_i2s_config_power_on[pin],
226 GPIO_CFG_ENABLE
227 );
228 if (rc < 0)
229 return rc;
230 }
231 } else if (mode == FM_I2S_OFF) {
232 pr_err("%s mode = FM_I2S_OFF", __func__);
233 for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_off);
234 pin++) {
235 rc = gpio_tlmm_config(
236 fm_i2s_config_power_off[pin],
237 GPIO_CFG_ENABLE
238 );
239 if (rc < 0)
240 return rc;
241 }
242 }
243 return rc;
244}
245static int config_pcm(int mode)
246{
247 int pin, rc = 0;
248
249 if (mode == BT_PCM_ON) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +0530250 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700251 config_pcm_i2s_mode(1);
252 pr_err("%s mode =BT_PCM_ON", __func__);
253 for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
254 pin++) {
255 rc = gpio_tlmm_config(bt_config_pcm_on[pin],
256 GPIO_CFG_ENABLE);
257 if (rc < 0)
258 return rc;
259 }
260 } else if (mode == BT_PCM_OFF) {
261 pr_err("%s mode =BT_PCM_OFF", __func__);
262 for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
263 pin++) {
264 rc = gpio_tlmm_config(bt_config_pcm_off[pin],
265 GPIO_CFG_ENABLE);
266 if (rc < 0)
267 return rc;
268 }
269
270 }
271
272 return rc;
273}
274
275static int msm_bahama_setup_pcm_i2s(int mode)
276{
277 int fm_state = 0, bt_state = 0;
278 int rc = 0;
279 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
280
281 fm_state = marimba_get_fm_status(&config);
282 bt_state = marimba_get_bt_status(&config);
283
284 switch (mode) {
285 case BT_PCM_ON:
286 case BT_PCM_OFF:
287 if (!fm_state)
288 rc = config_pcm(mode);
289 break;
290 case FM_I2S_ON:
291 rc = config_i2s(mode);
292 break;
293 case FM_I2S_OFF:
294 if (bt_state)
295 rc = config_pcm(BT_PCM_ON);
296 else
297 rc = config_i2s(mode);
298 break;
299 default:
300 rc = -EIO;
301 pr_err("%s:Unsupported mode", __func__);
302 }
303 return rc;
304}
305
Rahul Kashyap181d5552011-07-07 10:39:23 +0530306static int bt_set_gpio(int on)
307{
308 int rc = 0;
309 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
310
311 if (on) {
312 rc = gpio_direction_output(GPIO_BT_SYS_REST_EN, 1);
313 msleep(100);
314 } else {
315 if (!marimba_get_fm_status(&config) &&
316 !marimba_get_bt_status(&config)) {
317 gpio_set_value_cansleep(GPIO_BT_SYS_REST_EN, 0);
318 rc = gpio_direction_input(GPIO_BT_SYS_REST_EN);
319 msleep(100);
320 }
321 }
322 if (rc)
323 pr_err("%s: BT sys_reset_en GPIO : Error", __func__);
324
325 return rc;
326}
Justin Paupored98328e2011-08-19 13:48:31 -0700327static struct regulator *fm_regulator;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
329{
330 int rc = 0;
331 const char *id = "FMPW";
332 uint32_t irqcfg;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530333 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
334 u8 value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700335
336 /* Voting for 1.8V Regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700337 fm_regulator = regulator_get(NULL, "msme1");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700338 if (IS_ERR(fm_regulator)) {
Justin Paupored98328e2011-08-19 13:48:31 -0700339 rc = PTR_ERR(fm_regulator);
340 pr_err("%s: could not get regulator: %d\n", __func__, rc);
341 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700342 }
343
344 /* Set the voltage level to 1.8V */
Justin Paupored98328e2011-08-19 13:48:31 -0700345 rc = regulator_set_voltage(fm_regulator, 1800000, 1800000);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700346 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -0700347 pr_err("%s: could not set voltage: %d\n", __func__, rc);
348 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700349 }
350
351 /* Enabling the 1.8V regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700352 rc = regulator_enable(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700353 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -0700354 pr_err("%s: could not enable regulator: %d\n", __func__, rc);
355 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700356 }
357
358 /* Voting for 19.2MHz clock */
359 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
360 PMAPP_CLOCK_VOTE_ON);
361 if (rc < 0) {
362 pr_err("%s: clock vote failed with :(%d)\n",
363 __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700364 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700365 }
366
Rahul Kashyap181d5552011-07-07 10:39:23 +0530367 rc = bt_set_gpio(1);
368 if (rc) {
369 pr_err("%s: bt_set_gpio = %d", __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700370 goto gpio_deconfig;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530371 }
372 /*re-write FM Slave Id, after reset*/
373 value = BAHAMA_SLAVE_ID_FM_ADDR;
374 rc = marimba_write_bit_mask(&config,
375 BAHAMA_SLAVE_ID_FM_REG, &value, 1, 0xFF);
376 if (rc < 0) {
377 pr_err("%s: FM Slave ID rewrite Failed = %d", __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700378 goto gpio_deconfig;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530379 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700380 /* Configuring the FM GPIO */
381 irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
382 GPIO_CFG_2MA);
383
384 rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE);
385 if (rc) {
386 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
387 __func__, irqcfg, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700388 goto gpio_deconfig;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700389 }
390
391 return 0;
392
Justin Paupored98328e2011-08-19 13:48:31 -0700393gpio_deconfig:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700394 pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
395 PMAPP_CLOCK_VOTE_OFF);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530396 bt_set_gpio(0);
Justin Paupored98328e2011-08-19 13:48:31 -0700397reg_disable:
398 regulator_disable(fm_regulator);
399reg_free:
400 regulator_put(fm_regulator);
401 fm_regulator = NULL;
402out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700403 return rc;
404};
405
406static void fm_radio_shutdown(struct marimba_fm_platform_data *pdata)
407{
408 int rc;
409 const char *id = "FMPW";
410
411 /* Releasing the GPIO line used by FM */
412 uint32_t irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
413 GPIO_CFG_2MA);
414
415 rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE);
416 if (rc)
417 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
418 __func__, irqcfg, rc);
419
420 /* Releasing the 1.8V Regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700421 if (!IS_ERR_OR_NULL(fm_regulator)) {
422 rc = regulator_disable(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700423 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -0700424 pr_err("%s: could not disable regulator: %d\n",
425 __func__, rc);
426 regulator_put(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700427 fm_regulator = NULL;
428 }
429
430 /* Voting off the clock */
431 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
432 PMAPP_CLOCK_VOTE_OFF);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700433 if (rc < 0)
434 pr_err("%s: voting off failed with :(%d)\n",
435 __func__, rc);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530436 rc = bt_set_gpio(0);
437 if (rc)
438 pr_err("%s: bt_set_gpio = %d", __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700439}
440
441static struct marimba_fm_platform_data marimba_fm_pdata = {
442 .fm_setup = fm_radio_setup,
443 .fm_shutdown = fm_radio_shutdown,
444 .irq = MSM_GPIO_TO_INT(FM_GPIO),
445 .vreg_s2 = NULL,
446 .vreg_xo_out = NULL,
447 /* Configuring the FM SoC as I2S Master */
448 .is_fm_soc_i2s_master = true,
449 .config_i2s_gpio = msm_bahama_setup_pcm_i2s,
450};
451
Santosh Sajjan6822c682011-07-26 10:49:36 +0530452static struct platform_device msm_wlan_ar6000_pm_device = {
453 .name = "wlan_ar6000_pm_dev",
454 .id = -1,
455};
456
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700457static struct platform_device msm_bt_power_device = {
458 .name = "bt_power",
459};
Rahul Kashyap6e669462011-07-23 16:42:56 +0530460struct bahama_config_register {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700461 u8 reg;
462 u8 value;
463 u8 mask;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700464};
Rahul Kashyap6e669462011-07-23 16:42:56 +0530465struct bt_vreg_info {
466 const char *name;
467 unsigned int pmapp_id;
468 unsigned int level;
469 unsigned int is_pin_controlled;
Justin Paupored98328e2011-08-19 13:48:31 -0700470 struct regulator *reg;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530471};
472static struct bt_vreg_info bt_vregs[] = {
Justin Paupored98328e2011-08-19 13:48:31 -0700473 {"msme1", 2, 1800000, 0, NULL},
474 {"bt", 21, 2900000, 1, NULL}
Rahul Kashyap6e669462011-07-23 16:42:56 +0530475};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700476
477static int bahama_bt(int on)
478{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700479 int rc = 0;
480 int i;
481
482 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
483
484 struct bahama_variant_register {
485 const size_t size;
486 const struct bahama_config_register *set;
487 };
488
489 const struct bahama_config_register *p;
490
491 u8 version;
492
493 const struct bahama_config_register v10_bt_on[] = {
494 { 0xE9, 0x00, 0xFF },
495 { 0xF4, 0x80, 0xFF },
496 { 0xE4, 0x00, 0xFF },
497 { 0xE5, 0x00, 0x0F },
498#ifdef CONFIG_WLAN
499 { 0xE6, 0x38, 0x7F },
500 { 0xE7, 0x06, 0xFF },
501#endif
502 { 0xE9, 0x21, 0xFF },
503 { 0x01, 0x0C, 0x1F },
504 { 0x01, 0x08, 0x1F },
505 };
506
507 const struct bahama_config_register v20_bt_on_fm_off[] = {
508 { 0x11, 0x0C, 0xFF },
509 { 0x13, 0x01, 0xFF },
510 { 0xF4, 0x80, 0xFF },
511 { 0xF0, 0x00, 0xFF },
512 { 0xE9, 0x00, 0xFF },
513#ifdef CONFIG_WLAN
514 { 0x81, 0x00, 0x7F },
515 { 0x82, 0x00, 0xFF },
516 { 0xE6, 0x38, 0x7F },
517 { 0xE7, 0x06, 0xFF },
518#endif
519 { 0x8E, 0x15, 0xFF },
520 { 0x8F, 0x15, 0xFF },
521 { 0x90, 0x15, 0xFF },
522
523 { 0xE9, 0x21, 0xFF },
524 };
525
526 const struct bahama_config_register v20_bt_on_fm_on[] = {
527 { 0x11, 0x0C, 0xFF },
528 { 0x13, 0x01, 0xFF },
529 { 0xF4, 0x86, 0xFF },
530 { 0xF0, 0x06, 0xFF },
531 { 0xE9, 0x00, 0xFF },
532#ifdef CONFIG_WLAN
533 { 0x81, 0x00, 0x7F },
534 { 0x82, 0x00, 0xFF },
535 { 0xE6, 0x38, 0x7F },
536 { 0xE7, 0x06, 0xFF },
537#endif
538 { 0xE9, 0x21, 0xFF },
539 };
540
541 const struct bahama_config_register v10_bt_off[] = {
542 { 0xE9, 0x00, 0xFF },
543 };
544
545 const struct bahama_config_register v20_bt_off_fm_off[] = {
546 { 0xF4, 0x84, 0xFF },
547 { 0xF0, 0x04, 0xFF },
548 { 0xE9, 0x00, 0xFF }
549 };
550
551 const struct bahama_config_register v20_bt_off_fm_on[] = {
552 { 0xF4, 0x86, 0xFF },
553 { 0xF0, 0x06, 0xFF },
554 { 0xE9, 0x00, 0xFF }
555 };
556 const struct bahama_variant_register bt_bahama[2][3] = {
557 {
558 { ARRAY_SIZE(v10_bt_off), v10_bt_off },
559 { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
560 { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
561 },
562 {
563 { ARRAY_SIZE(v10_bt_on), v10_bt_on },
564 { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
565 { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
566 }
567 };
568
569 u8 offset = 0; /* index into bahama configs */
570 on = on ? 1 : 0;
571 version = marimba_read_bahama_ver(&config);
Rahul Kashyap92497af2011-07-07 12:13:52 +0530572 if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
573 dev_err(&msm_bt_power_device.dev, "%s: Bahama \
574 version read Error, version = %d \n",
575 __func__, version);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700576 return -EIO;
577 }
578
579 if (version == BAHAMA_VER_2_0) {
580 if (marimba_get_fm_status(&config))
581 offset = 0x01;
582 }
583
584 p = bt_bahama[on][version + offset].set;
585
586 dev_info(&msm_bt_power_device.dev,
587 "%s: found version %d\n", __func__, version);
588
589 for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
590 u8 value = (p+i)->value;
591 rc = marimba_write_bit_mask(&config,
592 (p+i)->reg,
593 &value,
594 sizeof((p+i)->value),
595 (p+i)->mask);
596 if (rc < 0) {
597 dev_err(&msm_bt_power_device.dev,
598 "%s: reg %x write failed: %d\n",
599 __func__, (p+i)->reg, rc);
600 return rc;
601 }
Rahul Kashyap92497af2011-07-07 12:13:52 +0530602 dev_dbg(&msm_bt_power_device.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700603 "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
604 __func__, (p+i)->reg,
605 value, (p+i)->mask);
606 value = 0;
607 rc = marimba_read_bit_mask(&config,
608 (p+i)->reg, &value,
609 sizeof((p+i)->value), (p+i)->mask);
610 if (rc < 0)
611 dev_err(&msm_bt_power_device.dev, "%s marimba_read_bit_mask- error",
612 __func__);
Rahul Kashyap92497af2011-07-07 12:13:52 +0530613 dev_dbg(&msm_bt_power_device.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700614 "%s: reg 0x%02x read value 0x%02x mask 0x%02x\n",
615 __func__, (p+i)->reg,
616 value, (p+i)->mask);
617 }
618 /* Update BT Status */
619 if (on)
620 marimba_set_bt_status(&config, true);
621 else
622 marimba_set_bt_status(&config, false);
623 return rc;
624}
625static int bluetooth_switch_regulators(int on)
626{
627 int i, rc = 0;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530628 const char *id = "BTPW";
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700629
Rahul Kashyap6e669462011-07-23 16:42:56 +0530630 for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
Justin Paupored98328e2011-08-19 13:48:31 -0700631 if (IS_ERR_OR_NULL(bt_vregs[i].reg)) {
632 rc = bt_vregs[i].reg ?
633 PTR_ERR(bt_vregs[i].reg) :
634 -ENODEV;
635 dev_err(&msm_bt_power_device.dev,
636 "%s: invalid regulator handle for %s: %d\n",
637 __func__, bt_vregs[i].name, rc);
638 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700639 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700640
Justin Paupored98328e2011-08-19 13:48:31 -0700641 if (bt_vregs[i].is_pin_controlled) {
642 rc = pmapp_vreg_pincntrl_vote(id,
Rahul Kashyap6e669462011-07-23 16:42:56 +0530643 bt_vregs[i].pmapp_id,
644 PMAPP_CLOCK_ID_D1,
645 on ? PMAPP_CLOCK_VOTE_ON :
Justin Paupored98328e2011-08-19 13:48:31 -0700646 PMAPP_CLOCK_VOTE_OFF);
647 } else {
648 rc = on ? regulator_enable(bt_vregs[i].reg) :
649 regulator_disable(bt_vregs[i].reg);
Rahul Kashyap6e669462011-07-23 16:42:56 +0530650 }
Justin Paupored98328e2011-08-19 13:48:31 -0700651
652 if (rc) {
653 dev_err(&msm_bt_power_device.dev,
654 "%s: could not %sable regulator %s: %d\n",
655 __func__, on ? "en" : "dis",
656 bt_vregs[i].name, rc);
657 i++;
658 goto reg_disable;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530659 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700660 }
Rahul Kashyap6e669462011-07-23 16:42:56 +0530661
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700662 return rc;
Justin Paupored98328e2011-08-19 13:48:31 -0700663
664reg_disable:
665 while (i--) {
666 if (bt_vregs[i].is_pin_controlled) {
667 pmapp_vreg_pincntrl_vote(id, bt_vregs[i].pmapp_id,
668 PMAPP_CLOCK_ID_D1,
669 on ? PMAPP_CLOCK_VOTE_OFF :
670 PMAPP_CLOCK_VOTE_ON);
671 } else {
672 if (on)
673 regulator_disable(bt_vregs[i].reg);
674 else
675 regulator_enable(bt_vregs[i].reg);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700676 }
Justin Paupored98328e2011-08-19 13:48:31 -0700677 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700678 return rc;
679}
680
Justin Paupored98328e2011-08-19 13:48:31 -0700681static struct regulator *reg_bahama;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700682static unsigned int msm_bahama_setup_power(void)
683{
684 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700685
Justin Paupored98328e2011-08-19 13:48:31 -0700686 reg_bahama = regulator_get(NULL, "msme1");
687 if (IS_ERR(reg_bahama)) {
688 rc = PTR_ERR(reg_bahama);
689 pr_err("%s: could not get regulator: %d\n", __func__, rc);
690 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700691 }
Justin Paupored98328e2011-08-19 13:48:31 -0700692
693 rc = regulator_set_voltage(reg_bahama, 1800000, 1800000);
694 if (rc) {
695 pr_err("%s: could not set voltage: %d\n", __func__, rc);
696 goto reg_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697 }
Justin Paupored98328e2011-08-19 13:48:31 -0700698
699 rc = regulator_enable(reg_bahama);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700700 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -0700701 pr_err("%s: could not enable regulator: %d\n", __func__, rc);
702 goto reg_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703 }
704
705 /*setup Bahama_sys_reset_n*/
706 rc = gpio_request(GPIO_BT_SYS_REST_EN, "bahama sys_rst_n");
Justin Paupored98328e2011-08-19 13:48:31 -0700707 if (rc) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700708 pr_err("%s: gpio_request %d = %d\n", __func__,
709 GPIO_BT_SYS_REST_EN, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700710 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700711 }
Justin Paupored98328e2011-08-19 13:48:31 -0700712
Rahul Kashyap181d5552011-07-07 10:39:23 +0530713 rc = bt_set_gpio(1);
Justin Paupored98328e2011-08-19 13:48:31 -0700714 if (rc) {
Rahul Kashyap181d5552011-07-07 10:39:23 +0530715 pr_err("%s: bt_set_gpio %d = %d\n", __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700716 GPIO_BT_SYS_REST_EN, rc);
717 goto gpio_fail;
718 }
Justin Paupored98328e2011-08-19 13:48:31 -0700719
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700720 return rc;
721
722gpio_fail:
723 gpio_free(GPIO_BT_SYS_REST_EN);
Justin Paupored98328e2011-08-19 13:48:31 -0700724reg_disable:
725 regulator_disable(reg_bahama);
726reg_fail:
727 regulator_put(reg_bahama);
728out:
729 reg_bahama = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700730 return rc;
731}
732
733static unsigned int msm_bahama_shutdown_power(int value)
734{
735 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700736
Justin Paupored98328e2011-08-19 13:48:31 -0700737 if (IS_ERR_OR_NULL(reg_bahama)) {
738 rc = reg_bahama ? PTR_ERR(reg_bahama) : -ENODEV;
739 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700740 }
Justin Paupored98328e2011-08-19 13:48:31 -0700741
742 rc = regulator_disable(reg_bahama);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700743 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -0700744 pr_err("%s: could not disable regulator: %d\n", __func__, rc);
745 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700746 }
Justin Paupored98328e2011-08-19 13:48:31 -0700747
Rahul Kashyape8698c62011-07-20 20:43:05 +0530748 if (value == BAHAMA_ID) {
749 rc = bt_set_gpio(0);
750 if (rc) {
751 pr_err("%s: bt_set_gpio = %d\n",
752 __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700753 goto reg_enable;
Rahul Kashyape8698c62011-07-20 20:43:05 +0530754 }
Justin Paupored98328e2011-08-19 13:48:31 -0700755 gpio_free(GPIO_BT_SYS_REST_EN);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530756 }
Justin Paupored98328e2011-08-19 13:48:31 -0700757
758 regulator_put(reg_bahama);
759 reg_bahama = NULL;
760
761 return 0;
762
763reg_enable:
764 regulator_enable(reg_bahama);
765out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766 return rc;
767}
768
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700769static unsigned int msm_bahama_core_config(int type)
770{
771 int rc = 0;
772
773 if (type == BAHAMA_ID) {
774 int i;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530775 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700776 const struct bahama_config_register v20_init[] = {
777 /* reg, value, mask */
778 { 0xF4, 0x84, 0xFF }, /* AREG */
779 { 0xF0, 0x04, 0xFF } /* DREG */
780 };
781 if (marimba_read_bahama_ver(&config) == BAHAMA_VER_2_0) {
782 for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
783 u8 value = v20_init[i].value;
784 rc = marimba_write_bit_mask(&config,
785 v20_init[i].reg,
786 &value,
787 sizeof(v20_init[i].value),
788 v20_init[i].mask);
789 if (rc < 0) {
790 pr_err("%s: reg %d write failed: %d\n",
791 __func__, v20_init[i].reg, rc);
792 return rc;
793 }
794 pr_debug("%s: reg 0x%02x value 0x%02x"
795 " mask 0x%02x\n",
796 __func__, v20_init[i].reg,
797 v20_init[i].value, v20_init[i].mask);
798 }
799 }
800 }
Rahul Kashyap181d5552011-07-07 10:39:23 +0530801 rc = bt_set_gpio(0);
802 if (rc) {
803 pr_err("%s: bt_set_gpio = %d\n",
804 __func__, rc);
805 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700806 pr_debug("core type: %d\n", type);
807 return rc;
808}
809
810static int bluetooth_power(int on)
811{
812 int pin, rc = 0;
813 const char *id = "BTPW";
814 int cid = 0;
815
816 cid = adie_get_detected_connectivity_type();
817 if (cid != BAHAMA_ID) {
818 pr_err("%s: unexpected adie connectivity type: %d\n",
819 __func__, cid);
820 return -ENODEV;
821 }
822 if (on) {
823 /*setup power for BT SOC*/
Rahul Kashyap181d5552011-07-07 10:39:23 +0530824 rc = bt_set_gpio(on);
825 if (rc) {
826 pr_err("%s: bt_set_gpio = %d\n",
827 __func__, rc);
828 goto exit;
829 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700830 rc = bluetooth_switch_regulators(on);
831 if (rc < 0) {
832 pr_err("%s: bluetooth_switch_regulators rc = %d",
833 __func__, rc);
834 goto exit;
835 }
836 /*setup BT GPIO lines*/
837 for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on);
838 pin++) {
839 rc = gpio_tlmm_config(bt_config_power_on[pin],
840 GPIO_CFG_ENABLE);
841 if (rc < 0) {
842 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
843 __func__,
844 bt_config_power_on[pin],
845 rc);
846 goto fail_power;
847 }
848 }
849 /*Setup BT clocks*/
850 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
851 PMAPP_CLOCK_VOTE_ON);
852 if (rc < 0) {
853 pr_err("Failed to vote for TCXO_D1 ON\n");
854 goto fail_clock;
855 }
856 msleep(20);
857
858 /*I2C config for Bahama*/
859 rc = bahama_bt(1);
860 if (rc < 0) {
861 pr_err("%s: bahama_bt rc = %d", __func__, rc);
862 goto fail_i2c;
863 }
864 msleep(20);
865
866 /*setup BT PCM lines*/
867 rc = msm_bahama_setup_pcm_i2s(BT_PCM_ON);
868 if (rc < 0) {
869 pr_err("%s: msm_bahama_setup_pcm_i2s , rc =%d\n",
870 __func__, rc);
871 goto fail_power;
872 }
873 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
874 PMAPP_CLOCK_VOTE_PIN_CTRL);
875 if (rc < 0)
876 pr_err("%s:Pin Control Failed, rc = %d",
877 __func__, rc);
878
879 } else {
880 rc = bahama_bt(0);
881 if (rc < 0)
882 pr_err("%s: bahama_bt rc = %d", __func__, rc);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530883
884 rc = bt_set_gpio(on);
885 if (rc) {
886 pr_err("%s: bt_set_gpio = %d\n",
887 __func__, rc);
888 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700889fail_i2c:
890 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
891 PMAPP_CLOCK_VOTE_OFF);
892 if (rc < 0)
893 pr_err("%s: Failed to vote Off D1\n", __func__);
894fail_clock:
895 for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off);
896 pin++) {
897 rc = gpio_tlmm_config(bt_config_power_off[pin],
898 GPIO_CFG_ENABLE);
899 if (rc < 0) {
900 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
901 __func__, bt_config_power_off[pin], rc);
902 }
903 }
904 rc = msm_bahama_setup_pcm_i2s(BT_PCM_OFF);
905 if (rc < 0) {
906 pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
907 __func__, rc);
908 }
909fail_power:
910 rc = bluetooth_switch_regulators(0);
911 if (rc < 0) {
912 pr_err("%s: switch_regulators : rc = %d",\
913 __func__, rc);
914 goto exit;
915 }
916 }
917 return rc;
918exit:
919 pr_err("%s: failed with rc = %d", __func__, rc);
920 return rc;
921}
922
923static int __init bt_power_init(void)
924{
925 int i, rc = 0;
Justin Paupored98328e2011-08-19 13:48:31 -0700926 struct device *dev = &msm_bt_power_device.dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700927
Justin Paupored98328e2011-08-19 13:48:31 -0700928 for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
929 bt_vregs[i].reg = regulator_get(dev, bt_vregs[i].name);
930 if (IS_ERR(bt_vregs[i].reg)) {
931 rc = PTR_ERR(bt_vregs[i].reg);
932 dev_err(dev, "%s: could not get regulator %s: %d\n",
933 __func__, bt_vregs[i].name, rc);
934 goto reg_get_fail;
935 }
936 rc = regulator_set_voltage(bt_vregs[i].reg,
937 bt_vregs[i].level, bt_vregs[i].level);
938 if (rc) {
939 dev_err(dev, "%s: could not set voltage for %s: %d\n",
940 __func__, bt_vregs[i].name, rc);
941 goto reg_set_fail;
942 }
943 }
944
945 dev->platform_data = &bluetooth_power;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700946
947 return rc;
948
Justin Paupored98328e2011-08-19 13:48:31 -0700949reg_set_fail:
950 i++;
951reg_get_fail:
952 while (i--) {
953 regulator_put(bt_vregs[i].reg);
954 bt_vregs[i].reg = NULL;
955 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700956 return rc;
957}
958
959static struct marimba_platform_data marimba_pdata = {
960 .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,
961 .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
962 .bahama_setup = msm_bahama_setup_power,
963 .bahama_shutdown = msm_bahama_shutdown_power,
964 .bahama_core_config = msm_bahama_core_config,
965 .fm = &marimba_fm_pdata,
966};
967
968#endif
969
970#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
971static struct i2c_board_info core_exp_i2c_info[] __initdata = {
972 {
973 I2C_BOARD_INFO("sx1509q", 0x3e),
974 },
975};
976static struct i2c_board_info cam_exp_i2c_info[] __initdata = {
977 {
978 I2C_BOARD_INFO("sx1508q", 0x22),
979 .platform_data = &sx150x_data[SX150X_CAM],
980 },
981};
982#endif
983#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
984static struct i2c_board_info bahama_devices[] = {
985{
986 I2C_BOARD_INFO("marimba", 0xc),
987 .platform_data = &marimba_pdata,
988},
989};
990#endif
991
992#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
993static void __init register_i2c_devices(void)
994{
995
996 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
997 cam_exp_i2c_info,
998 ARRAY_SIZE(cam_exp_i2c_info));
999
Trilok Soni3d0f6c52011-07-26 16:06:58 +05301000 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001001 sx150x_data[SX150X_CORE].io_open_drain_ena = 0xe0f0;
1002
1003 core_exp_i2c_info[0].platform_data =
1004 &sx150x_data[SX150X_CORE];
1005
1006 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
1007 core_exp_i2c_info,
1008 ARRAY_SIZE(core_exp_i2c_info));
1009#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
1010 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
1011 bahama_devices,
1012 ARRAY_SIZE(bahama_devices));
1013#endif
1014}
1015#endif
1016
1017static struct msm_gpio qup_i2c_gpios_io[] = {
1018 { GPIO_CFG(60, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1019 "qup_scl" },
1020 { GPIO_CFG(61, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1021 "qup_sda" },
1022 { GPIO_CFG(131, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1023 "qup_scl" },
1024 { GPIO_CFG(132, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1025 "qup_sda" },
1026};
1027
1028static struct msm_gpio qup_i2c_gpios_hw[] = {
1029 { GPIO_CFG(60, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1030 "qup_scl" },
1031 { GPIO_CFG(61, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1032 "qup_sda" },
1033 { GPIO_CFG(131, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1034 "qup_scl" },
1035 { GPIO_CFG(132, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1036 "qup_sda" },
1037};
1038
1039static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
1040{
1041 int rc;
1042
1043 if (adap_id < 0 || adap_id > 1)
1044 return;
1045
1046 /* Each adapter gets 2 lines from the table */
1047 if (config_type)
1048 rc = msm_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
1049 else
1050 rc = msm_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
1051 if (rc < 0)
1052 pr_err("QUP GPIO request/enable failed: %d\n", rc);
1053}
1054
1055static struct msm_i2c_platform_data msm_gsbi0_qup_i2c_pdata = {
1056 .clk_freq = 100000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001057 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
1058};
1059
1060static struct msm_i2c_platform_data msm_gsbi1_qup_i2c_pdata = {
1061 .clk_freq = 100000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001062 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
1063};
1064
1065#ifdef CONFIG_ARCH_MSM7X27A
Prabhanjan Kandula1d920742011-08-19 10:28:11 +05301066#define MSM_PMEM_MDP_SIZE 0x1900000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001067#define MSM_PMEM_ADSP_SIZE 0x1000000
1068
1069#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
1070#define MSM_FB_SIZE 0x260000
1071#else
1072#define MSM_FB_SIZE 0x195000
1073#endif
1074
1075#endif
1076
1077static struct android_usb_platform_data android_usb_pdata = {
1078 .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
1079};
1080
1081static struct platform_device android_usb_device = {
1082 .name = "android_usb",
1083 .id = -1,
1084 .dev = {
1085 .platform_data = &android_usb_pdata,
1086 },
1087};
1088
1089#ifdef CONFIG_USB_EHCI_MSM_72K
1090static void msm_hsusb_vbus_power(unsigned phy_info, int on)
1091{
1092 int rc = 0;
1093 unsigned gpio;
1094
1095 gpio = GPIO_HOST_VBUS_EN;
1096
1097 rc = gpio_request(gpio, "i2c_host_vbus_en");
1098 if (rc < 0) {
1099 pr_err("failed to request %d GPIO\n", gpio);
1100 return;
1101 }
1102 gpio_direction_output(gpio, !!on);
1103 gpio_set_value_cansleep(gpio, !!on);
1104 gpio_free(gpio);
1105}
1106
1107static struct msm_usb_host_platform_data msm_usb_host_pdata = {
1108 .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_45NM),
1109};
1110
1111static void __init msm7x2x_init_host(void)
1112{
1113 msm_add_host(0, &msm_usb_host_pdata);
1114}
1115#endif
1116
1117#ifdef CONFIG_USB_MSM_OTG_72K
1118static int hsusb_rpc_connect(int connect)
1119{
1120 if (connect)
1121 return msm_hsusb_rpc_connect();
1122 else
1123 return msm_hsusb_rpc_close();
1124}
1125
Justin Paupored98328e2011-08-19 13:48:31 -07001126static struct regulator *reg_hsusb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001127static int msm_hsusb_ldo_init(int init)
1128{
Justin Paupored98328e2011-08-19 13:48:31 -07001129 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001130
Justin Paupored98328e2011-08-19 13:48:31 -07001131 if (init) {
1132 reg_hsusb = regulator_get(NULL, "usb");
1133 if (IS_ERR(reg_hsusb)) {
1134 rc = PTR_ERR(reg_hsusb);
1135 pr_err("%s: could not get regulator: %d\n",
1136 __func__, rc);
1137 goto out;
1138 }
1139
1140 rc = regulator_set_voltage(reg_hsusb, 3300000, 3300000);
1141 if (rc) {
1142 pr_err("%s: could not set voltage: %d\n",
1143 __func__, rc);
1144 goto reg_free;
1145 }
1146
1147 return 0;
1148 }
1149 /* else fall through */
1150reg_free:
1151 regulator_put(reg_hsusb);
1152out:
1153 reg_hsusb = NULL;
1154 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001155}
1156
1157static int msm_hsusb_ldo_enable(int enable)
1158{
1159 static int ldo_status;
1160
Justin Paupored98328e2011-08-19 13:48:31 -07001161 if (IS_ERR_OR_NULL(reg_hsusb))
1162 return reg_hsusb ? PTR_ERR(reg_hsusb) : -ENODEV;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001163
1164 if (ldo_status == enable)
1165 return 0;
1166
1167 ldo_status = enable;
1168
Justin Paupored98328e2011-08-19 13:48:31 -07001169 return enable ?
1170 regulator_enable(reg_hsusb) :
1171 regulator_disable(reg_hsusb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001172}
1173
1174#ifndef CONFIG_USB_EHCI_MSM_72K
1175static int msm_hsusb_pmic_notif_init(void (*callback)(int online), int init)
1176{
1177 int ret = 0;
1178
1179 if (init)
1180 ret = msm_pm_app_rpc_init(callback);
1181 else
1182 msm_pm_app_rpc_deinit(callback);
1183
1184 return ret;
1185}
1186#endif
1187
1188static struct msm_otg_platform_data msm_otg_pdata = {
1189#ifndef CONFIG_USB_EHCI_MSM_72K
1190 .pmic_vbus_notif_init = msm_hsusb_pmic_notif_init,
1191#else
1192 .vbus_power = msm_hsusb_vbus_power,
1193#endif
1194 .rpc_connect = hsusb_rpc_connect,
1195 .core_clk = 1,
1196 .pemp_level = PRE_EMPHASIS_WITH_20_PERCENT,
1197 .cdr_autoreset = CDR_AUTO_RESET_DISABLE,
1198 .drv_ampl = HS_DRV_AMPLITUDE_DEFAULT,
1199 .se1_gating = SE1_GATING_DISABLE,
1200 .ldo_init = msm_hsusb_ldo_init,
1201 .ldo_enable = msm_hsusb_ldo_enable,
1202 .chg_init = hsusb_chg_init,
1203 .chg_connected = hsusb_chg_connected,
1204 .chg_vbus_draw = hsusb_chg_vbus_draw,
1205};
1206#endif
1207
1208static struct msm_hsusb_gadget_platform_data msm_gadget_pdata = {
1209 .is_phy_status_timer_on = 1,
1210};
1211
1212static struct resource smc91x_resources[] = {
1213 [0] = {
1214 .start = 0x90000300,
1215 .end = 0x900003ff,
1216 .flags = IORESOURCE_MEM,
1217 },
1218 [1] = {
1219 .start = MSM_GPIO_TO_INT(4),
1220 .end = MSM_GPIO_TO_INT(4),
1221 .flags = IORESOURCE_IRQ,
1222 },
1223};
1224
1225static struct platform_device smc91x_device = {
1226 .name = "smc91x",
1227 .id = 0,
1228 .num_resources = ARRAY_SIZE(smc91x_resources),
1229 .resource = smc91x_resources,
1230};
1231
1232#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT)\
1233 || defined(CONFIG_MMC_MSM_SDC2_SUPPORT)\
1234 || defined(CONFIG_MMC_MSM_SDC3_SUPPORT)\
1235 || defined(CONFIG_MMC_MSM_SDC4_SUPPORT))
1236
1237static unsigned long vreg_sts, gpio_sts;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001238
1239struct sdcc_gpio {
1240 struct msm_gpio *cfg_data;
1241 uint32_t size;
1242 struct msm_gpio *sleep_cfg_data;
1243};
1244
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301245/**
1246 * Due to insufficient drive strengths for SDC GPIO lines some old versioned
1247 * SD/MMC cards may cause data CRC errors. Hence, set optimal values
1248 * for SDC slots based on timing closure and marginality. SDC1 slot
1249 * require higher value since it should handle bad signal quality due
1250 * to size of T-flash adapters.
1251 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001252static struct msm_gpio sdc1_cfg_data[] = {
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301253 {GPIO_CFG(51, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001254 "sdc1_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301255 {GPIO_CFG(52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001256 "sdc1_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301257 {GPIO_CFG(53, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001258 "sdc1_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301259 {GPIO_CFG(54, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001260 "sdc1_dat_0"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301261 {GPIO_CFG(55, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001262 "sdc1_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301263 {GPIO_CFG(56, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001264 "sdc1_clk"},
1265};
1266
1267static struct msm_gpio sdc2_cfg_data[] = {
1268 {GPIO_CFG(62, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1269 "sdc2_clk"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301270 {GPIO_CFG(63, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001271 "sdc2_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301272 {GPIO_CFG(64, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001273 "sdc2_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301274 {GPIO_CFG(65, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001275 "sdc2_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301276 {GPIO_CFG(66, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001277 "sdc2_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301278 {GPIO_CFG(67, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001279 "sdc2_dat_0"},
1280};
1281
1282static struct msm_gpio sdc2_sleep_cfg_data[] = {
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301283 {GPIO_CFG(62, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001284 "sdc2_clk"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301285 {GPIO_CFG(63, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001286 "sdc2_cmd"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301287 {GPIO_CFG(64, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001288 "sdc2_dat_3"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301289 {GPIO_CFG(65, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001290 "sdc2_dat_2"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301291 {GPIO_CFG(66, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001292 "sdc2_dat_1"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301293 {GPIO_CFG(67, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001294 "sdc2_dat_0"},
1295};
1296static struct msm_gpio sdc3_cfg_data[] = {
1297 {GPIO_CFG(88, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1298 "sdc3_clk"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301299 {GPIO_CFG(89, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001300 "sdc3_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301301 {GPIO_CFG(90, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001302 "sdc3_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301303 {GPIO_CFG(91, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001304 "sdc3_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301305 {GPIO_CFG(92, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001306 "sdc3_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301307 {GPIO_CFG(93, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001308 "sdc3_dat_0"},
1309#ifdef CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301310 {GPIO_CFG(19, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001311 "sdc3_dat_7"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301312 {GPIO_CFG(20, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001313 "sdc3_dat_6"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301314 {GPIO_CFG(21, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001315 "sdc3_dat_5"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301316 {GPIO_CFG(108, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001317 "sdc3_dat_4"},
1318#endif
1319};
1320
1321static struct msm_gpio sdc4_cfg_data[] = {
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301322 {GPIO_CFG(19, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001323 "sdc4_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301324 {GPIO_CFG(20, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001325 "sdc4_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301326 {GPIO_CFG(21, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001327 "sdc4_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301328 {GPIO_CFG(107, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001329 "sdc4_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301330 {GPIO_CFG(108, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001331 "sdc4_dat_0"},
1332 {GPIO_CFG(109, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1333 "sdc4_clk"},
1334};
1335
1336static struct sdcc_gpio sdcc_cfg_data[] = {
1337 {
1338 .cfg_data = sdc1_cfg_data,
1339 .size = ARRAY_SIZE(sdc1_cfg_data),
1340 },
1341 {
1342 .cfg_data = sdc2_cfg_data,
1343 .size = ARRAY_SIZE(sdc2_cfg_data),
1344 .sleep_cfg_data = sdc2_sleep_cfg_data,
1345 },
1346 {
1347 .cfg_data = sdc3_cfg_data,
1348 .size = ARRAY_SIZE(sdc3_cfg_data),
1349 },
1350 {
1351 .cfg_data = sdc4_cfg_data,
1352 .size = ARRAY_SIZE(sdc4_cfg_data),
1353 },
1354};
1355
Justin Paupored98328e2011-08-19 13:48:31 -07001356static struct regulator *sdcc_vreg_data[ARRAY_SIZE(sdcc_cfg_data)];
1357
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001358static int msm_sdcc_setup_gpio(int dev_id, unsigned int enable)
1359{
1360 int rc = 0;
1361 struct sdcc_gpio *curr;
1362
1363 curr = &sdcc_cfg_data[dev_id - 1];
1364 if (!(test_bit(dev_id, &gpio_sts)^enable))
1365 return rc;
1366
1367 if (enable) {
1368 set_bit(dev_id, &gpio_sts);
1369 rc = msm_gpios_request_enable(curr->cfg_data, curr->size);
1370 if (rc)
1371 pr_err("%s: Failed to turn on GPIOs for slot %d\n",
1372 __func__, dev_id);
1373 } else {
1374 clear_bit(dev_id, &gpio_sts);
1375 if (curr->sleep_cfg_data) {
1376 rc = msm_gpios_enable(curr->sleep_cfg_data, curr->size);
1377 msm_gpios_free(curr->sleep_cfg_data, curr->size);
1378 return rc;
1379 }
1380 msm_gpios_disable_free(curr->cfg_data, curr->size);
1381 }
1382 return rc;
1383}
1384
1385static int msm_sdcc_setup_vreg(int dev_id, unsigned int enable)
1386{
1387 int rc = 0;
Justin Paupored98328e2011-08-19 13:48:31 -07001388 struct regulator *curr = sdcc_vreg_data[dev_id - 1];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001389
Justin Paupored98328e2011-08-19 13:48:31 -07001390 if (test_bit(dev_id, &vreg_sts) == enable)
1391 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001392
Justin Paupored98328e2011-08-19 13:48:31 -07001393 if (!curr)
1394 return -ENODEV;
1395
1396 if (IS_ERR(curr))
1397 return PTR_ERR(curr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001398
1399 if (enable) {
1400 set_bit(dev_id, &vreg_sts);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001401
Justin Paupored98328e2011-08-19 13:48:31 -07001402 rc = regulator_enable(curr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001403 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -07001404 pr_err("%s: could not enable regulator: %d\n",
1405 __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001406 } else {
1407 clear_bit(dev_id, &vreg_sts);
Justin Paupored98328e2011-08-19 13:48:31 -07001408
1409 rc = regulator_disable(curr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001410 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -07001411 pr_err("%s: could not disable regulator: %d\n",
1412 __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001413 }
1414 return rc;
1415}
1416
1417static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
1418{
1419 int rc = 0;
1420 struct platform_device *pdev;
1421
1422 pdev = container_of(dv, struct platform_device, dev);
1423
1424 rc = msm_sdcc_setup_gpio(pdev->id, !!vdd);
1425 if (rc)
1426 goto out;
1427
1428 rc = msm_sdcc_setup_vreg(pdev->id, !!vdd);
1429out:
1430 return rc;
1431}
1432
1433#define GPIO_SDC1_HW_DET 85
1434
1435#if defined(CONFIG_MMC_MSM_SDC1_SUPPORT) \
1436 && defined(CONFIG_MMC_MSM_CARD_HW_DETECTION)
1437static unsigned int msm7x2xa_sdcc_slot_status(struct device *dev)
1438{
1439 int status;
1440
1441 status = gpio_tlmm_config(GPIO_CFG(GPIO_SDC1_HW_DET, 2, GPIO_CFG_INPUT,
1442 GPIO_CFG_PULL_UP, GPIO_CFG_8MA), GPIO_CFG_ENABLE);
1443 if (status)
1444 pr_err("%s:Failed to configure tlmm for GPIO %d\n", __func__,
1445 GPIO_SDC1_HW_DET);
1446
1447 status = gpio_request(GPIO_SDC1_HW_DET, "SD_HW_Detect");
1448 if (status) {
1449 pr_err("%s:Failed to request GPIO %d\n", __func__,
1450 GPIO_SDC1_HW_DET);
1451 } else {
1452 status = gpio_direction_input(GPIO_SDC1_HW_DET);
1453 if (!status)
1454 status = gpio_get_value(GPIO_SDC1_HW_DET);
1455 gpio_free(GPIO_SDC1_HW_DET);
1456 }
1457 return status;
1458}
1459#endif
1460
1461#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
1462static struct mmc_platform_data sdc1_plat_data = {
1463 .ocr_mask = MMC_VDD_28_29,
1464 .translate_vdd = msm_sdcc_setup_power,
1465 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1466 .msmsdcc_fmin = 144000,
1467 .msmsdcc_fmid = 24576000,
1468 .msmsdcc_fmax = 49152000,
1469#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
1470 .status = msm7x2xa_sdcc_slot_status,
1471 .status_irq = MSM_GPIO_TO_INT(GPIO_SDC1_HW_DET),
1472 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1473#endif
1474};
1475#endif
1476
1477#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
1478static struct mmc_platform_data sdc2_plat_data = {
1479 /*
1480 * SDC2 supports only 1.8V, claim for 2.85V range is just
1481 * for allowing buggy cards who advertise 2.8V even though
1482 * they can operate at 1.8V supply.
1483 */
1484 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_165_195,
1485 .translate_vdd = msm_sdcc_setup_power,
1486 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1487#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
1488 .sdiowakeup_irq = MSM_GPIO_TO_INT(66),
1489#endif
1490 .msmsdcc_fmin = 144000,
1491 .msmsdcc_fmid = 24576000,
1492 .msmsdcc_fmax = 49152000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001493};
1494#endif
1495
1496#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
1497static struct mmc_platform_data sdc3_plat_data = {
1498 .ocr_mask = MMC_VDD_28_29,
1499 .translate_vdd = msm_sdcc_setup_power,
1500#ifdef CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT
1501 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
1502#else
1503 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1504#endif
1505 .msmsdcc_fmin = 144000,
1506 .msmsdcc_fmid = 24576000,
1507 .msmsdcc_fmax = 49152000,
1508 .nonremovable = 1,
1509};
1510#endif
1511
1512#if (defined(CONFIG_MMC_MSM_SDC4_SUPPORT)\
1513 && !defined(CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT))
1514static struct mmc_platform_data sdc4_plat_data = {
1515 .ocr_mask = MMC_VDD_28_29,
1516 .translate_vdd = msm_sdcc_setup_power,
1517 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1518 .msmsdcc_fmin = 144000,
1519 .msmsdcc_fmid = 24576000,
1520 .msmsdcc_fmax = 49152000,
1521};
1522#endif
Pankaj Kumarb3e55c62011-09-26 11:59:39 +05301523
1524static int __init mmc_regulator_init(int sdcc_no, const char *supply, int uV)
1525{
1526 int rc;
1527
1528 BUG_ON(sdcc_no < 1 || sdcc_no > 4);
1529
1530 sdcc_no--;
1531
1532 sdcc_vreg_data[sdcc_no] = regulator_get(NULL, supply);
1533
1534 if (IS_ERR(sdcc_vreg_data[sdcc_no])) {
1535 rc = PTR_ERR(sdcc_vreg_data[sdcc_no]);
1536 pr_err("%s: could not get regulator \"%s\": %d\n",
1537 __func__, supply, rc);
1538 goto out;
1539 }
1540
1541 rc = regulator_set_voltage(sdcc_vreg_data[sdcc_no], uV, uV);
1542
1543 if (rc) {
1544 pr_err("%s: could not set voltage for \"%s\" to %d uV: %d\n",
1545 __func__, supply, uV, rc);
1546 goto reg_free;
1547 }
1548
1549 return rc;
1550
1551reg_free:
1552 regulator_put(sdcc_vreg_data[sdcc_no]);
1553out:
1554 sdcc_vreg_data[sdcc_no] = NULL;
1555 return rc;
1556}
1557
1558static void __init msm7x27a_init_mmc(void)
1559{
1560 /* eMMC slot */
1561#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
1562 if (mmc_regulator_init(3, "emmc", 3000000))
1563 return;
1564 msm_add_sdcc(3, &sdc3_plat_data);
1565#endif
1566 /* Micro-SD slot */
1567#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
1568 if (mmc_regulator_init(1, "mmc", 2850000))
1569 return;
1570 msm_add_sdcc(1, &sdc1_plat_data);
1571#endif
1572 /* SDIO WLAN slot */
1573#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
1574 if (mmc_regulator_init(2, "mmc", 2850000))
1575 return;
1576 msm_add_sdcc(2, &sdc2_plat_data);
1577#endif
1578 /* Not Used */
1579#if (defined(CONFIG_MMC_MSM_SDC4_SUPPORT)\
1580 && !defined(CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT))
1581 if (mmc_regulator_init(4, "mmc", 2850000))
1582 return;
1583 msm_add_sdcc(4, &sdc4_plat_data);
1584#endif
1585}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001586#endif
1587
1588#ifdef CONFIG_SERIAL_MSM_HS
1589static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = {
1590 .inject_rx_on_wakeup = 1,
1591 .rx_to_inject = 0xFD,
1592};
1593#endif
1594static struct msm_pm_platform_data msm7x27a_pm_data[MSM_PM_SLEEP_MODE_NR] = {
1595 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
1596 .idle_supported = 1,
1597 .suspend_supported = 1,
1598 .idle_enabled = 1,
1599 .suspend_enabled = 1,
1600 .latency = 16000,
1601 .residency = 20000,
1602 },
1603 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
1604 .idle_supported = 1,
1605 .suspend_supported = 1,
1606 .idle_enabled = 1,
1607 .suspend_enabled = 1,
1608 .latency = 12000,
1609 .residency = 20000,
1610 },
1611 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
1612 .idle_supported = 1,
1613 .suspend_supported = 1,
1614 .idle_enabled = 0,
1615 .suspend_enabled = 1,
1616 .latency = 2000,
1617 .residency = 0,
1618 },
1619 [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
1620 .idle_supported = 1,
1621 .suspend_supported = 1,
1622 .idle_enabled = 1,
1623 .suspend_enabled = 1,
1624 .latency = 2,
1625 .residency = 0,
1626 },
1627};
1628
1629static struct android_pmem_platform_data android_pmem_adsp_pdata = {
1630 .name = "pmem_adsp",
1631 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
Mahesh Lankac6af7eb2011-08-02 18:00:35 +05301632 .cached = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001633 .memory_type = MEMTYPE_EBI1,
1634};
1635
1636static struct platform_device android_pmem_adsp_device = {
1637 .name = "android_pmem",
1638 .id = 1,
1639 .dev = { .platform_data = &android_pmem_adsp_pdata },
1640};
1641
1642static unsigned pmem_mdp_size = MSM_PMEM_MDP_SIZE;
1643static int __init pmem_mdp_size_setup(char *p)
1644{
1645 pmem_mdp_size = memparse(p, NULL);
1646 return 0;
1647}
1648
1649early_param("pmem_mdp_size", pmem_mdp_size_setup);
1650
1651static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
1652static int __init pmem_adsp_size_setup(char *p)
1653{
1654 pmem_adsp_size = memparse(p, NULL);
1655 return 0;
1656}
1657
1658early_param("pmem_adsp_size", pmem_adsp_size_setup);
1659
1660static unsigned fb_size = MSM_FB_SIZE;
1661static int __init fb_size_setup(char *p)
1662{
1663 fb_size = memparse(p, NULL);
1664 return 0;
1665}
1666
1667early_param("fb_size", fb_size_setup);
1668
Justin Paupored98328e2011-08-19 13:48:31 -07001669static struct regulator_bulk_data regs_lcdc[] = {
1670 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
1671 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001672};
1673
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001674static uint32_t lcdc_gpio_initialized;
1675
1676static void lcdc_toshiba_gpio_init(void)
1677{
Justin Paupored98328e2011-08-19 13:48:31 -07001678 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001679 if (!lcdc_gpio_initialized) {
1680 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
1681 pr_err("failed to request gpio spi_clk\n");
1682 return;
1683 }
1684 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
1685 pr_err("failed to request gpio spi_cs0_N\n");
1686 goto fail_gpio6;
1687 }
1688 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
1689 pr_err("failed to request gpio spi_mosi\n");
1690 goto fail_gpio5;
1691 }
1692 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
1693 pr_err("failed to request gpio spi_miso\n");
1694 goto fail_gpio4;
1695 }
1696 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
1697 pr_err("failed to request gpio_disp_pwr\n");
1698 goto fail_gpio3;
1699 }
1700 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
1701 pr_err("failed to request gpio_bkl_en\n");
1702 goto fail_gpio2;
1703 }
1704 pmapp_disp_backlight_init();
1705
Justin Paupored98328e2011-08-19 13:48:31 -07001706 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc), regs_lcdc);
1707 if (rc) {
1708 pr_err("%s: could not get regulators: %d\n",
1709 __func__, rc);
1710 goto fail_gpio1;
1711 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001712
Justin Paupored98328e2011-08-19 13:48:31 -07001713 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
1714 regs_lcdc);
1715 if (rc) {
1716 pr_err("%s: could not set voltages: %d\n",
1717 __func__, rc);
1718 goto fail_vreg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001719 }
1720 lcdc_gpio_initialized = 1;
1721 }
1722 return;
Justin Paupored98328e2011-08-19 13:48:31 -07001723fail_vreg:
1724 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001725fail_gpio1:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001726 gpio_free(GPIO_BACKLIGHT_EN);
1727fail_gpio2:
1728 gpio_free(GPIO_DISPLAY_PWR_EN);
1729fail_gpio3:
1730 gpio_free(GPIO_SPI_MISO);
1731fail_gpio4:
1732 gpio_free(GPIO_SPI_MOSI);
1733fail_gpio5:
1734 gpio_free(GPIO_SPI_CS0_N);
1735fail_gpio6:
1736 gpio_free(GPIO_SPI_CLK);
1737 lcdc_gpio_initialized = 0;
1738}
1739
1740static uint32_t lcdc_gpio_table[] = {
1741 GPIO_SPI_CLK,
1742 GPIO_SPI_CS0_N,
1743 GPIO_SPI_MOSI,
1744 GPIO_DISPLAY_PWR_EN,
1745 GPIO_BACKLIGHT_EN,
1746 GPIO_SPI_MISO,
1747};
1748
1749static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
1750{
1751 int n;
1752
1753 if (lcdc_gpio_initialized) {
1754 /* All are IO Expander GPIOs */
1755 for (n = 0; n < (len - 1); n++)
1756 gpio_direction_output(table[n], 1);
1757 }
1758}
1759
1760static void lcdc_toshiba_config_gpios(int enable)
1761{
1762 config_lcdc_gpio_table(lcdc_gpio_table,
1763 ARRAY_SIZE(lcdc_gpio_table), enable);
1764}
1765
1766static int msm_fb_lcdc_power_save(int on)
1767{
Justin Paupored98328e2011-08-19 13:48:31 -07001768 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001769 /* Doing the init of the LCDC GPIOs very late as they are from
1770 an I2C-controlled IO Expander */
1771 lcdc_toshiba_gpio_init();
1772
1773 if (lcdc_gpio_initialized) {
1774 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1775 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
1776
Justin Paupored98328e2011-08-19 13:48:31 -07001777 rc = on ? regulator_bulk_enable(
1778 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
1779 regulator_bulk_disable(
1780 ARRAY_SIZE(regs_lcdc), regs_lcdc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001781
Justin Paupored98328e2011-08-19 13:48:31 -07001782 if (rc)
1783 pr_err("%s: could not %sable regulators: %d\n",
1784 __func__, on ? "en" : "dis", rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001785 }
1786
1787 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001788}
1789
1790
1791static int lcdc_toshiba_set_bl(int level)
1792{
1793 int ret;
1794
1795 ret = pmapp_disp_backlight_set_brightness(level);
1796 if (ret)
1797 pr_err("%s: can't set lcd backlight!\n", __func__);
1798
1799 return ret;
1800}
1801
1802
1803static struct lcdc_platform_data lcdc_pdata = {
Jeevan Shriram15f2a5e2011-07-13 21:45:26 +05301804 .lcdc_gpio_config = NULL,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001805 .lcdc_power_save = msm_fb_lcdc_power_save,
1806};
1807
1808static int lcd_panel_spi_gpio_num[] = {
1809 GPIO_SPI_MOSI, /* spi_sdi */
1810 GPIO_SPI_MISO, /* spi_sdoi */
1811 GPIO_SPI_CLK, /* spi_clk */
1812 GPIO_SPI_CS0_N, /* spi_cs */
1813};
1814
1815static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
1816 .panel_config_gpio = lcdc_toshiba_config_gpios,
1817 .pmic_backlight = lcdc_toshiba_set_bl,
1818 .gpio_num = lcd_panel_spi_gpio_num,
1819};
1820
1821static struct platform_device lcdc_toshiba_panel_device = {
1822 .name = "lcdc_toshiba_fwvga_pt",
1823 .id = 0,
1824 .dev = {
1825 .platform_data = &lcdc_toshiba_panel_data,
1826 }
1827};
1828
1829static struct resource msm_fb_resources[] = {
1830 {
1831 .flags = IORESOURCE_DMA,
1832 }
1833};
1834
1835static int msm_fb_detect_panel(const char *name)
1836{
1837 int ret = -EPERM;
1838
Trilok Soni3d0f6c52011-07-26 16:06:58 +05301839 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001840 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21))
1841 ret = 0;
1842 } else {
1843 ret = -ENODEV;
1844 }
1845
1846 return ret;
1847}
1848
1849static struct msm_fb_platform_data msm_fb_pdata = {
1850 .detect_client = msm_fb_detect_panel,
1851};
1852
1853static struct platform_device msm_fb_device = {
1854 .name = "msm_fb",
1855 .id = 0,
1856 .num_resources = ARRAY_SIZE(msm_fb_resources),
1857 .resource = msm_fb_resources,
1858 .dev = {
1859 .platform_data = &msm_fb_pdata,
1860 }
1861};
1862
1863#ifdef CONFIG_FB_MSM_MIPI_DSI
1864static int mipi_renesas_set_bl(int level)
1865{
1866 int ret;
1867
1868 ret = pmapp_disp_backlight_set_brightness(level);
1869
1870 if (ret)
1871 pr_err("%s: can't set lcd backlight!\n", __func__);
1872
1873 return ret;
1874}
1875
1876static struct msm_panel_common_pdata mipi_renesas_pdata = {
1877 .pmic_backlight = mipi_renesas_set_bl,
1878};
1879
1880
1881static struct platform_device mipi_dsi_renesas_panel_device = {
1882 .name = "mipi_renesas",
1883 .id = 0,
1884 .dev = {
1885 .platform_data = &mipi_renesas_pdata,
1886 }
1887};
1888#endif
1889
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001890#define SND(desc, num) { .name = #desc, .id = num }
1891static struct snd_endpoint snd_endpoints_list[] = {
1892 SND(HANDSET, 0),
1893 SND(MONO_HEADSET, 2),
1894 SND(HEADSET, 3),
1895 SND(SPEAKER, 6),
1896 SND(TTY_HEADSET, 8),
1897 SND(TTY_VCO, 9),
1898 SND(TTY_HCO, 10),
1899 SND(BT, 12),
1900 SND(IN_S_SADC_OUT_HANDSET, 16),
1901 SND(IN_S_SADC_OUT_SPEAKER_PHONE, 25),
1902 SND(FM_DIGITAL_STEREO_HEADSET, 26),
1903 SND(FM_DIGITAL_SPEAKER_PHONE, 27),
1904 SND(FM_DIGITAL_BT_A2DP_HEADSET, 28),
Sidipotu Ashokab34ca42011-07-22 16:34:20 +05301905 SND(CURRENT, 0x7FFFFFFE),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001906 SND(FM_ANALOG_STEREO_HEADSET, 35),
1907 SND(FM_ANALOG_STEREO_HEADSET_CODEC, 36),
1908};
1909#undef SND
1910
1911static struct msm_snd_endpoints msm_device_snd_endpoints = {
1912 .endpoints = snd_endpoints_list,
1913 .num = sizeof(snd_endpoints_list) / sizeof(struct snd_endpoint)
1914};
1915
1916static struct platform_device msm_device_snd = {
1917 .name = "msm_snd",
1918 .id = -1,
1919 .dev = {
1920 .platform_data = &msm_device_snd_endpoints
1921 },
1922};
1923
1924#define DEC0_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1925 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1926 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1927 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1928 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1929 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1930#define DEC1_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1931 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1932 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1933 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1934 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1935 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1936#define DEC2_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1937 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1938 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1939 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1940 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1941 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1942#define DEC3_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1943 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1944 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1945 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1946 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1947 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1948#define DEC4_FORMAT (1<<MSM_ADSP_CODEC_MIDI)
1949
1950static unsigned int dec_concurrency_table[] = {
1951 /* Audio LP */
1952 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DMA)), 0,
1953 0, 0, 0,
1954
1955 /* Concurrency 1 */
1956 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1957 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1958 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1959 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1960 (DEC4_FORMAT),
1961
1962 /* Concurrency 2 */
1963 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1964 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1965 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1966 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1967 (DEC4_FORMAT),
1968
1969 /* Concurrency 3 */
1970 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1971 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1972 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1973 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1974 (DEC4_FORMAT),
1975
1976 /* Concurrency 4 */
1977 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1978 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1979 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1980 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1981 (DEC4_FORMAT),
1982
1983 /* Concurrency 5 */
1984 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1985 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1986 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1987 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1988 (DEC4_FORMAT),
1989
1990 /* Concurrency 6 */
1991 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1992 0, 0, 0, 0,
1993
1994 /* Concurrency 7 */
1995 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1996 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1997 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1998 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1999 (DEC4_FORMAT),
2000};
2001
2002#define DEC_INFO(name, queueid, decid, nr_codec) { .module_name = name, \
2003 .module_queueid = queueid, .module_decid = decid, \
2004 .nr_codec_support = nr_codec}
2005
2006static struct msm_adspdec_info dec_info_list[] = {
2007 DEC_INFO("AUDPLAY0TASK", 13, 0, 11), /* AudPlay0BitStreamCtrlQueue */
2008 DEC_INFO("AUDPLAY1TASK", 14, 1, 11), /* AudPlay1BitStreamCtrlQueue */
2009 DEC_INFO("AUDPLAY2TASK", 15, 2, 11), /* AudPlay2BitStreamCtrlQueue */
2010 DEC_INFO("AUDPLAY3TASK", 16, 3, 11), /* AudPlay3BitStreamCtrlQueue */
2011 DEC_INFO("AUDPLAY4TASK", 17, 4, 1), /* AudPlay4BitStreamCtrlQueue */
2012};
2013
2014static struct msm_adspdec_database msm_device_adspdec_database = {
2015 .num_dec = ARRAY_SIZE(dec_info_list),
2016 .num_concurrency_support = (ARRAY_SIZE(dec_concurrency_table) / \
2017 ARRAY_SIZE(dec_info_list)),
2018 .dec_concurrency_table = dec_concurrency_table,
2019 .dec_info_list = dec_info_list,
2020};
2021
2022static struct platform_device msm_device_adspdec = {
2023 .name = "msm_adspdec",
2024 .id = -1,
2025 .dev = {
2026 .platform_data = &msm_device_adspdec_database
2027 },
2028};
2029
2030static struct android_pmem_platform_data android_pmem_audio_pdata = {
2031 .name = "pmem_audio",
2032 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2033 .cached = 0,
2034 .memory_type = MEMTYPE_EBI1,
2035};
2036
2037static struct platform_device android_pmem_audio_device = {
2038 .name = "android_pmem",
2039 .id = 2,
2040 .dev = { .platform_data = &android_pmem_audio_pdata },
2041};
2042
2043static struct android_pmem_platform_data android_pmem_pdata = {
2044 .name = "pmem",
2045 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2046 .cached = 1,
2047 .memory_type = MEMTYPE_EBI1,
2048};
2049static struct platform_device android_pmem_device = {
2050 .name = "android_pmem",
2051 .id = 0,
2052 .dev = { .platform_data = &android_pmem_pdata },
2053};
2054
2055static u32 msm_calculate_batt_capacity(u32 current_voltage);
2056
2057static struct msm_psy_batt_pdata msm_psy_batt_data = {
2058 .voltage_min_design = 2800,
2059 .voltage_max_design = 4300,
2060 .avail_chg_sources = AC_CHG | USB_CHG ,
2061 .batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
2062 .calculate_capacity = &msm_calculate_batt_capacity,
2063};
2064
2065static u32 msm_calculate_batt_capacity(u32 current_voltage)
2066{
2067 u32 low_voltage = msm_psy_batt_data.voltage_min_design;
2068 u32 high_voltage = msm_psy_batt_data.voltage_max_design;
2069
2070 return (current_voltage - low_voltage) * 100
2071 / (high_voltage - low_voltage);
2072}
2073
2074static struct platform_device msm_batt_device = {
2075 .name = "msm-battery",
2076 .id = -1,
2077 .dev.platform_data = &msm_psy_batt_data,
2078};
2079
2080static struct smsc911x_platform_config smsc911x_config = {
2081 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
2082 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
2083 .flags = SMSC911X_USE_16BIT,
2084};
2085
2086static struct resource smsc911x_resources[] = {
2087 [0] = {
2088 .start = 0x90000000,
2089 .end = 0x90007fff,
2090 .flags = IORESOURCE_MEM,
2091 },
2092 [1] = {
2093 .start = MSM_GPIO_TO_INT(48),
2094 .end = MSM_GPIO_TO_INT(48),
2095 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
2096 },
2097};
2098
2099static struct platform_device smsc911x_device = {
2100 .name = "smsc911x",
2101 .id = 0,
2102 .num_resources = ARRAY_SIZE(smsc911x_resources),
2103 .resource = smsc911x_resources,
2104 .dev = {
2105 .platform_data = &smsc911x_config,
2106 },
2107};
2108
2109static struct msm_gpio smsc911x_gpios[] = {
2110 { GPIO_CFG(48, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
2111 "smsc911x_irq" },
2112 { GPIO_CFG(49, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
2113 "eth_fifo_sel" },
2114};
2115
2116#define ETH_FIFO_SEL_GPIO 49
2117static void msm7x27a_cfg_smsc911x(void)
2118{
2119 int res;
2120
2121 res = msm_gpios_request_enable(smsc911x_gpios,
2122 ARRAY_SIZE(smsc911x_gpios));
2123 if (res) {
2124 pr_err("%s: unable to enable gpios for SMSC911x\n", __func__);
2125 return;
2126 }
2127
2128 /* ETH_FIFO_SEL */
2129 res = gpio_direction_output(ETH_FIFO_SEL_GPIO, 0);
2130 if (res) {
2131 pr_err("%s: unable to get direction for gpio %d\n", __func__,
2132 ETH_FIFO_SEL_GPIO);
2133 msm_gpios_disable_free(smsc911x_gpios,
2134 ARRAY_SIZE(smsc911x_gpios));
2135 return;
2136 }
2137 gpio_set_value(ETH_FIFO_SEL_GPIO, 0);
2138}
2139
2140#ifdef CONFIG_MSM_CAMERA
2141static uint32_t camera_off_gpio_table[] = {
2142 GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
2143};
2144
2145static uint32_t camera_on_gpio_table[] = {
2146 GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
2147};
2148
2149#ifdef CONFIG_MSM_CAMERA_FLASH
2150static struct msm_camera_sensor_flash_src msm_flash_src = {
Nishant Pandit474f2252011-07-23 23:17:56 +05302151 .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
2152 ._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
2153 ._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002154};
2155#endif
2156
Justin Paupored98328e2011-08-19 13:48:31 -07002157static struct regulator_bulk_data regs_camera[] = {
2158 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
2159 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
2160 { .supply = "usb2", .min_uV = 1800000, .max_uV = 1800000 },
2161};
2162
2163static void __init msm_camera_vreg_init(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002164{
2165 int rc;
2166
Justin Paupored98328e2011-08-19 13:48:31 -07002167 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002168
Justin Paupored98328e2011-08-19 13:48:31 -07002169 if (rc) {
2170 pr_err("%s: could not get regulators: %d\n", __func__, rc);
2171 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002172 }
2173
Justin Paupored98328e2011-08-19 13:48:31 -07002174 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002175
Justin Paupored98328e2011-08-19 13:48:31 -07002176 if (rc) {
2177 pr_err("%s: could not set voltages: %d\n", __func__, rc);
2178 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002179 }
Justin Paupored98328e2011-08-19 13:48:31 -07002180}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002181
Justin Paupored98328e2011-08-19 13:48:31 -07002182static void msm_camera_vreg_config(int vreg_en)
2183{
2184 int rc = vreg_en ?
2185 regulator_bulk_enable(ARRAY_SIZE(regs_camera), regs_camera) :
2186 regulator_bulk_disable(ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002187
Justin Paupored98328e2011-08-19 13:48:31 -07002188 if (rc)
2189 pr_err("%s: could not %sable regulators: %d\n",
2190 __func__, vreg_en ? "en" : "dis", rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002191}
2192
2193static int config_gpio_table(uint32_t *table, int len)
2194{
2195 int rc = 0, i = 0;
2196
2197 for (i = 0; i < len; i++) {
2198 rc = gpio_tlmm_config(table[i], GPIO_CFG_ENABLE);
2199 if (rc) {
2200 pr_err("%s not able to get gpio\n", __func__);
2201 for (i--; i >= 0; i--)
2202 gpio_tlmm_config(camera_off_gpio_table[i],
2203 GPIO_CFG_ENABLE);
2204 break;
2205 }
2206 }
2207 return rc;
2208}
2209
2210static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data;
2211static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data;
2212static int config_camera_on_gpios_rear(void)
2213{
2214 int rc = 0;
2215
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302216 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002217 msm_camera_vreg_config(1);
2218
2219 rc = config_gpio_table(camera_on_gpio_table,
2220 ARRAY_SIZE(camera_on_gpio_table));
2221 if (rc < 0) {
2222 pr_err("%s: CAMSENSOR gpio table request"
2223 "failed\n", __func__);
2224 return rc;
2225 }
2226
2227 return rc;
2228}
2229
2230static void config_camera_off_gpios_rear(void)
2231{
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302232 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002233 msm_camera_vreg_config(0);
2234
2235 config_gpio_table(camera_off_gpio_table,
2236 ARRAY_SIZE(camera_off_gpio_table));
2237}
2238
2239static int config_camera_on_gpios_front(void)
2240{
2241 int rc = 0;
2242
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302243 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002244 msm_camera_vreg_config(1);
2245
2246 rc = config_gpio_table(camera_on_gpio_table,
2247 ARRAY_SIZE(camera_on_gpio_table));
2248 if (rc < 0) {
2249 pr_err("%s: CAMSENSOR gpio table request"
2250 "failed\n", __func__);
2251 return rc;
2252 }
2253
2254 return rc;
2255}
2256
2257static void config_camera_off_gpios_front(void)
2258{
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302259 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002260 msm_camera_vreg_config(0);
2261
2262 config_gpio_table(camera_off_gpio_table,
2263 ARRAY_SIZE(camera_off_gpio_table));
2264}
2265
2266struct msm_camera_device_platform_data msm_camera_device_data_rear = {
2267 .camera_gpio_on = config_camera_on_gpios_rear,
2268 .camera_gpio_off = config_camera_off_gpios_rear,
2269 .ioext.csiphy = 0xA1000000,
2270 .ioext.csisz = 0x00100000,
2271 .ioext.csiirq = INT_CSI_IRQ_1,
2272 .ioclk.mclk_clk_rate = 24000000,
2273 .ioclk.vfe_clk_rate = 192000000,
2274 .ioext.appphy = MSM_CLK_CTL_PHYS,
2275 .ioext.appsz = MSM_CLK_CTL_SIZE,
2276};
2277
2278struct msm_camera_device_platform_data msm_camera_device_data_front = {
2279 .camera_gpio_on = config_camera_on_gpios_front,
2280 .camera_gpio_off = config_camera_off_gpios_front,
2281 .ioext.csiphy = 0xA0F00000,
2282 .ioext.csisz = 0x00100000,
2283 .ioext.csiirq = INT_CSI_IRQ_0,
2284 .ioclk.mclk_clk_rate = 24000000,
2285 .ioclk.vfe_clk_rate = 192000000,
2286 .ioext.appphy = MSM_CLK_CTL_PHYS,
2287 .ioext.appsz = MSM_CLK_CTL_SIZE,
2288};
2289
2290#ifdef CONFIG_S5K4E1
2291static struct msm_camera_sensor_platform_info s5k4e1_sensor_7627a_info = {
2292 .mount_angle = 90
2293};
2294
2295static struct msm_camera_sensor_flash_data flash_s5k4e1 = {
2296 .flash_type = MSM_CAMERA_FLASH_LED,
2297 .flash_src = &msm_flash_src
2298};
2299
2300static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
2301 .sensor_name = "s5k4e1",
2302 .sensor_reset_enable = 1,
2303 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N,
2304 .sensor_pwd = 85,
2305 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
2306 .vcm_enable = 1,
2307 .pdata = &msm_camera_device_data_rear,
2308 .flash_data = &flash_s5k4e1,
2309 .sensor_platform_info = &s5k4e1_sensor_7627a_info,
2310 .csi_if = 1
2311};
2312
2313static struct platform_device msm_camera_sensor_s5k4e1 = {
2314 .name = "msm_camera_s5k4e1",
2315 .dev = {
2316 .platform_data = &msm_camera_sensor_s5k4e1_data,
2317 },
2318};
2319#endif
2320
2321#ifdef CONFIG_IMX072
2322static struct msm_camera_sensor_platform_info imx072_sensor_7627a_info = {
2323 .mount_angle = 90
2324};
2325
2326static struct msm_camera_sensor_flash_data flash_imx072 = {
2327 .flash_type = MSM_CAMERA_FLASH_LED,
2328 .flash_src = &msm_flash_src
2329};
2330
2331static struct msm_camera_sensor_info msm_camera_sensor_imx072_data = {
2332 .sensor_name = "imx072",
2333 .sensor_reset_enable = 1,
2334 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N, /* TODO 106,*/
2335 .sensor_pwd = 85,
2336 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
2337 .vcm_enable = 1,
2338 .pdata = &msm_camera_device_data_rear,
2339 .flash_data = &flash_imx072,
2340 .sensor_platform_info = &imx072_sensor_7627a_info,
2341 .csi_if = 1
2342};
2343
2344static struct platform_device msm_camera_sensor_imx072 = {
2345 .name = "msm_camera_imx072",
2346 .dev = {
2347 .platform_data = &msm_camera_sensor_imx072_data,
2348 },
2349};
2350#endif
2351
2352#ifdef CONFIG_WEBCAM_OV9726
2353static struct msm_camera_sensor_platform_info ov9726_sensor_7627a_info = {
2354 .mount_angle = 90
2355};
2356
2357static struct msm_camera_sensor_flash_data flash_ov9726 = {
2358 .flash_type = MSM_CAMERA_FLASH_NONE,
2359 .flash_src = &msm_flash_src
2360};
2361
2362static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
2363 .sensor_name = "ov9726",
2364 .sensor_reset_enable = 0,
2365 .sensor_reset = GPIO_CAM_GP_CAM1MP_XCLR,
2366 .sensor_pwd = 85,
2367 .vcm_pwd = 1,
2368 .vcm_enable = 0,
2369 .pdata = &msm_camera_device_data_front,
2370 .flash_data = &flash_ov9726,
2371 .sensor_platform_info = &ov9726_sensor_7627a_info,
2372 .csi_if = 1
2373};
2374
2375static struct platform_device msm_camera_sensor_ov9726 = {
2376 .name = "msm_camera_ov9726",
2377 .dev = {
2378 .platform_data = &msm_camera_sensor_ov9726_data,
2379 },
2380};
Justin Paupored98328e2011-08-19 13:48:31 -07002381#else
2382static inline void msm_camera_vreg_init(void) { }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002383#endif
2384
2385#ifdef CONFIG_MT9E013
2386static struct msm_camera_sensor_platform_info mt9e013_sensor_7627a_info = {
2387 .mount_angle = 90
2388};
2389
2390static struct msm_camera_sensor_flash_data flash_mt9e013 = {
2391 .flash_type = MSM_CAMERA_FLASH_LED,
2392 .flash_src = &msm_flash_src
2393};
2394
2395static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
2396 .sensor_name = "mt9e013",
2397 .sensor_reset = 0,
2398 .sensor_reset_enable = 1,
2399 .sensor_pwd = 85,
2400 .vcm_pwd = 1,
2401 .vcm_enable = 0,
2402 .pdata = &msm_camera_device_data_rear,
2403 .flash_data = &flash_mt9e013,
2404 .sensor_platform_info = &mt9e013_sensor_7627a_info,
2405 .csi_if = 1
2406};
2407
2408static struct platform_device msm_camera_sensor_mt9e013 = {
2409 .name = "msm_camera_mt9e013",
2410 .dev = {
2411 .platform_data = &msm_camera_sensor_mt9e013_data,
2412 },
2413};
2414#endif
2415
2416static struct i2c_board_info i2c_camera_devices[] = {
2417 #ifdef CONFIG_S5K4E1
2418 {
2419 I2C_BOARD_INFO("s5k4e1", 0x36),
2420 },
2421 {
2422 I2C_BOARD_INFO("s5k4e1_af", 0x8c >> 1),
2423 },
2424 #endif
2425 #ifdef CONFIG_WEBCAM_OV9726
2426 {
2427 I2C_BOARD_INFO("ov9726", 0x10),
2428 },
2429 #endif
2430 #ifdef CONFIG_IMX072
2431 {
2432 I2C_BOARD_INFO("imx072", 0x34),
2433 },
2434 #endif
2435 #ifdef CONFIG_MT9E013
2436 {
2437 I2C_BOARD_INFO("mt9e013", 0x6C >> 2),
2438 },
2439 #endif
2440 {
Nishant Pandit474f2252011-07-23 23:17:56 +05302441 I2C_BOARD_INFO("sc628a", 0x6E),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002442 },
2443};
2444#endif
2445#if defined(CONFIG_SERIAL_MSM_HSL_CONSOLE) \
2446 && defined(CONFIG_MSM_SHARED_GPIO_FOR_UART2DM)
2447static struct msm_gpio uart2dm_gpios[] = {
2448 {GPIO_CFG(19, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2449 "uart2dm_rfr_n" },
2450 {GPIO_CFG(20, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2451 "uart2dm_cts_n" },
2452 {GPIO_CFG(21, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2453 "uart2dm_rx" },
2454 {GPIO_CFG(108, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2455 "uart2dm_tx" },
2456};
2457
2458static void msm7x27a_cfg_uart2dm_serial(void)
2459{
2460 int ret;
2461 ret = msm_gpios_request_enable(uart2dm_gpios,
2462 ARRAY_SIZE(uart2dm_gpios));
2463 if (ret)
2464 pr_err("%s: unable to enable gpios for uart2dm\n", __func__);
2465}
2466#else
2467static void msm7x27a_cfg_uart2dm_serial(void) { }
2468#endif
2469
2470static struct platform_device *rumi_sim_devices[] __initdata = {
2471 &msm_device_dmov,
2472 &msm_device_smd,
2473 &smc91x_device,
2474 &msm_device_uart1,
2475 &msm_device_nand,
2476 &msm_device_uart_dm1,
2477 &msm_gsbi0_qup_i2c_device,
2478 &msm_gsbi1_qup_i2c_device,
2479};
2480
2481static struct platform_device *surf_ffa_devices[] __initdata = {
2482 &msm_device_dmov,
2483 &msm_device_smd,
2484 &msm_device_uart1,
2485 &msm_device_uart_dm1,
2486 &msm_device_uart_dm2,
2487 &msm_device_nand,
2488 &msm_gsbi0_qup_i2c_device,
2489 &msm_gsbi1_qup_i2c_device,
2490 &msm_device_otg,
2491 &msm_device_gadget_peripheral,
2492 &android_usb_device,
2493 &android_pmem_device,
2494 &android_pmem_adsp_device,
2495 &android_pmem_audio_device,
2496 &msm_device_snd,
2497 &msm_device_adspdec,
2498 &msm_fb_device,
2499 &lcdc_toshiba_panel_device,
2500 &msm_batt_device,
2501 &smsc911x_device,
2502#ifdef CONFIG_S5K4E1
2503 &msm_camera_sensor_s5k4e1,
2504#endif
2505#ifdef CONFIG_IMX072
2506 &msm_camera_sensor_imx072,
2507#endif
2508#ifdef CONFIG_WEBCAM_OV9726
2509 &msm_camera_sensor_ov9726,
2510#endif
2511#ifdef CONFIG_MT9E013
2512 &msm_camera_sensor_mt9e013,
2513#endif
2514#ifdef CONFIG_FB_MSM_MIPI_DSI
2515 &mipi_dsi_renesas_panel_device,
2516#endif
2517 &msm_kgsl_3d0,
2518#ifdef CONFIG_BT
2519 &msm_bt_power_device,
2520#endif
Manish Dewangan3a260992011-06-24 18:01:34 +05302521 &asoc_msm_pcm,
2522 &asoc_msm_dai0,
2523 &asoc_msm_dai1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002524};
2525
2526static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
2527static int __init pmem_kernel_ebi1_size_setup(char *p)
2528{
2529 pmem_kernel_ebi1_size = memparse(p, NULL);
2530 return 0;
2531}
2532early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
2533
2534static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
2535static int __init pmem_audio_size_setup(char *p)
2536{
2537 pmem_audio_size = memparse(p, NULL);
2538 return 0;
2539}
2540early_param("pmem_audio_size", pmem_audio_size_setup);
2541
2542static void __init msm_msm7x2x_allocate_memory_regions(void)
2543{
2544 void *addr;
2545 unsigned long size;
2546
2547 size = fb_size ? : MSM_FB_SIZE;
2548 addr = alloc_bootmem_align(size, 0x1000);
2549 msm_fb_resources[0].start = __pa(addr);
2550 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
2551 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
2552 size, addr, __pa(addr));
2553}
2554
2555static struct memtype_reserve msm7x27a_reserve_table[] __initdata = {
2556 [MEMTYPE_SMI] = {
2557 },
2558 [MEMTYPE_EBI0] = {
2559 .flags = MEMTYPE_FLAGS_1M_ALIGN,
2560 },
2561 [MEMTYPE_EBI1] = {
2562 .flags = MEMTYPE_FLAGS_1M_ALIGN,
2563 },
2564};
2565
2566static void __init size_pmem_devices(void)
2567{
2568#ifdef CONFIG_ANDROID_PMEM
2569 android_pmem_adsp_pdata.size = pmem_adsp_size;
2570 android_pmem_pdata.size = pmem_mdp_size;
2571 android_pmem_audio_pdata.size = pmem_audio_size;
2572#endif
2573}
2574
2575static void __init reserve_memory_for(struct android_pmem_platform_data *p)
2576{
2577 msm7x27a_reserve_table[p->memory_type].size += p->size;
2578}
2579
2580static void __init reserve_pmem_memory(void)
2581{
2582#ifdef CONFIG_ANDROID_PMEM
2583 reserve_memory_for(&android_pmem_adsp_pdata);
2584 reserve_memory_for(&android_pmem_pdata);
2585 reserve_memory_for(&android_pmem_audio_pdata);
2586 msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
2587#endif
2588}
2589
2590static void __init msm7x27a_calculate_reserve_sizes(void)
2591{
2592 size_pmem_devices();
2593 reserve_pmem_memory();
2594}
2595
2596static int msm7x27a_paddr_to_memtype(unsigned int paddr)
2597{
2598 return MEMTYPE_EBI1;
2599}
2600
2601static struct reserve_info msm7x27a_reserve_info __initdata = {
2602 .memtype_reserve_table = msm7x27a_reserve_table,
2603 .calculate_reserve_sizes = msm7x27a_calculate_reserve_sizes,
2604 .paddr_to_memtype = msm7x27a_paddr_to_memtype,
2605};
2606
2607static void __init msm7x27a_reserve(void)
2608{
2609 reserve_info = &msm7x27a_reserve_info;
2610 msm_reserve();
2611}
2612
2613static void __init msm_device_i2c_init(void)
2614{
2615 msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
2616 msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
2617}
2618
2619static struct msm_panel_common_pdata mdp_pdata = {
2620 .gpio = 97,
2621 .mdp_rev = MDP_REV_303,
2622};
2623
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302624
2625#ifdef CONFIG_FB_MSM
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002626#define GPIO_LCDC_BRDG_PD 128
2627#define GPIO_LCDC_BRDG_RESET_N 129
2628
2629#define LCDC_RESET_PHYS 0x90008014
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302630
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002631static void __iomem *lcdc_reset_ptr;
2632
2633static unsigned mipi_dsi_gpio[] = {
2634 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2635 GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
2636 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2637 GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
2638};
2639
2640enum {
2641 DSI_SINGLE_LANE = 1,
2642 DSI_TWO_LANES,
2643};
2644
2645static int msm_fb_get_lane_config(void)
2646{
2647 int rc = DSI_TWO_LANES;
2648
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302649 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002650 rc = DSI_SINGLE_LANE;
2651 pr_info("DSI Single Lane\n");
2652 } else {
2653 pr_info("DSI Two Lanes\n");
2654 }
2655 return rc;
2656}
2657
2658static int msm_fb_dsi_client_reset(void)
2659{
2660 int rc = 0;
2661
2662 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
2663 if (rc < 0) {
2664 pr_err("failed to request lcd brdg reset_n\n");
2665 return rc;
2666 }
2667
2668 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
2669 if (rc < 0) {
2670 pr_err("failed to request lcd brdg pd\n");
2671 return rc;
2672 }
2673
2674 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
2675 if (rc) {
2676 pr_err("Failed to enable LCDC Bridge reset enable\n");
2677 goto gpio_error;
2678 }
2679
2680 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
2681 if (rc) {
2682 pr_err("Failed to enable LCDC Bridge pd enable\n");
2683 goto gpio_error2;
2684 }
2685
2686 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
2687 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
2688 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
2689
2690 if (!rc) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302691 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002692 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
2693 sizeof(uint32_t));
2694
2695 if (!lcdc_reset_ptr)
2696 return 0;
2697 }
2698 return rc;
2699 } else {
2700 goto gpio_error;
2701 }
2702
2703gpio_error2:
2704 pr_err("Failed GPIO bridge pd\n");
2705 gpio_free(GPIO_LCDC_BRDG_PD);
2706
2707gpio_error:
2708 pr_err("Failed GPIO bridge reset\n");
2709 gpio_free(GPIO_LCDC_BRDG_RESET_N);
2710 return rc;
2711}
2712
Justin Paupored98328e2011-08-19 13:48:31 -07002713static struct regulator_bulk_data regs_dsi[] = {
2714 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
2715 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002716};
2717
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002718static int dsi_gpio_initialized;
2719
2720static int mipi_dsi_panel_power(int on)
2721{
Justin Paupored98328e2011-08-19 13:48:31 -07002722 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002723 uint32_t lcdc_reset_cfg;
2724
2725 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
Justin Paupored98328e2011-08-19 13:48:31 -07002726 if (unlikely(!dsi_gpio_initialized)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002727 pmapp_disp_backlight_init();
2728
2729 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
2730 if (rc < 0) {
2731 pr_err("failed to request gpio_disp_pwr\n");
2732 return rc;
2733 }
2734
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302735 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002736 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
2737 if (rc < 0) {
2738 pr_err("failed to enable display pwr\n");
2739 goto fail_gpio1;
2740 }
2741
2742 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
2743 if (rc < 0) {
2744 pr_err("failed to request gpio_bkl_en\n");
2745 goto fail_gpio1;
2746 }
2747
2748 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
2749 if (rc < 0) {
2750 pr_err("failed to enable backlight\n");
2751 goto fail_gpio2;
2752 }
2753 }
2754
Justin Paupored98328e2011-08-19 13:48:31 -07002755 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
2756 if (rc) {
2757 pr_err("%s: could not get regulators: %d\n",
2758 __func__, rc);
2759 goto fail_gpio2;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002760 }
Justin Paupored98328e2011-08-19 13:48:31 -07002761
2762 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi), regs_dsi);
2763 if (rc) {
2764 pr_err("%s: could not set voltages: %d\n",
2765 __func__, rc);
2766 goto fail_vreg;
2767 }
2768
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002769 dsi_gpio_initialized = 1;
2770 }
2771
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302772 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Justin Paupored98328e2011-08-19 13:48:31 -07002773 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
2774 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302775 } else if (machine_is_msm7x27a_ffa() ||
2776 machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002777 if (on) {
Justin Paupored98328e2011-08-19 13:48:31 -07002778 /* This line drives an active low pin on FFA */
2779 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
2780 if (rc < 0)
2781 pr_err("failed to set direction for "
2782 "display pwr\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002783 } else {
Justin Paupored98328e2011-08-19 13:48:31 -07002784 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
2785 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
2786 if (rc < 0)
2787 pr_err("failed to set direction for "
2788 "display pwr\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002789 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002790 }
2791
Justin Paupored98328e2011-08-19 13:48:31 -07002792 if (on) {
2793 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
2794
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302795 if (machine_is_msm7x27a_surf() ||
2796 machine_is_msm7625a_surf()) {
Justin Paupored98328e2011-08-19 13:48:31 -07002797 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
2798 rmb();
2799 lcdc_reset_cfg &= ~1;
2800
2801 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
2802 msleep(20);
2803 wmb();
2804 lcdc_reset_cfg |= 1;
2805 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
2806 } else {
2807 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
2808 msleep(20);
2809 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
2810 }
2811
2812 if (pmapp_disp_backlight_set_brightness(100))
2813 pr_err("backlight set brightness failed\n");
2814 } else {
2815 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
2816
2817 if (pmapp_disp_backlight_set_brightness(0))
2818 pr_err("backlight set brightness failed\n");
2819 }
2820
2821 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
2822 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
2823
2824 if (rc)
2825 pr_err("%s: could not %sable regulators: %d\n",
2826 __func__, on ? "en" : "dis", rc);
2827
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002828 return rc;
2829
Justin Paupored98328e2011-08-19 13:48:31 -07002830fail_vreg:
2831 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002832fail_gpio2:
2833 gpio_free(GPIO_BACKLIGHT_EN);
2834fail_gpio1:
2835 gpio_free(GPIO_DISPLAY_PWR_EN);
2836 dsi_gpio_initialized = 0;
2837 return rc;
2838}
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302839#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002840
2841#define MDP_303_VSYNC_GPIO 97
2842
2843#ifdef CONFIG_FB_MSM_MDP303
2844static struct mipi_dsi_platform_data mipi_dsi_pdata = {
2845 .vsync_gpio = MDP_303_VSYNC_GPIO,
2846 .dsi_power_save = mipi_dsi_panel_power,
2847 .dsi_client_reset = msm_fb_dsi_client_reset,
2848 .get_lane_config = msm_fb_get_lane_config,
2849};
2850#endif
2851
2852static void __init msm_fb_add_devices(void)
2853{
2854 msm_fb_register_device("mdp", &mdp_pdata);
2855 msm_fb_register_device("lcdc", &lcdc_pdata);
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302856#ifdef CONFIG_FB_MSM_MDP303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002857 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302858#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002859}
2860
2861#define MSM_EBI2_PHYS 0xa0d00000
2862#define MSM_EBI2_XMEM_CS2_CFG1 0xa0d10030
2863
2864static void __init msm7x27a_init_ebi2(void)
2865{
2866 uint32_t ebi2_cfg;
2867 void __iomem *ebi2_cfg_ptr;
2868
2869 ebi2_cfg_ptr = ioremap_nocache(MSM_EBI2_PHYS, sizeof(uint32_t));
2870 if (!ebi2_cfg_ptr)
2871 return;
2872
2873 ebi2_cfg = readl(ebi2_cfg_ptr);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302874 if (machine_is_msm7x27a_rumi3() || machine_is_msm7x27a_surf() ||
2875 machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002876 ebi2_cfg |= (1 << 4); /* CS2 */
2877
2878 writel(ebi2_cfg, ebi2_cfg_ptr);
2879 iounmap(ebi2_cfg_ptr);
2880
2881 /* Enable A/D MUX[bit 31] from EBI2_XMEM_CS2_CFG1 */
2882 ebi2_cfg_ptr = ioremap_nocache(MSM_EBI2_XMEM_CS2_CFG1,
2883 sizeof(uint32_t));
2884 if (!ebi2_cfg_ptr)
2885 return;
2886
2887 ebi2_cfg = readl(ebi2_cfg_ptr);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302888 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002889 ebi2_cfg |= (1 << 31);
2890
2891 writel(ebi2_cfg, ebi2_cfg_ptr);
2892 iounmap(ebi2_cfg_ptr);
2893}
2894
2895#define ATMEL_TS_I2C_NAME "maXTouch"
Justin Paupored98328e2011-08-19 13:48:31 -07002896
2897static struct regulator_bulk_data regs_atmel[] = {
2898 { .supply = "ldo2", .min_uV = 2850000, .max_uV = 2850000 },
2899 { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
2900};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002901
2902#define ATMEL_TS_GPIO_IRQ 82
2903
2904static int atmel_ts_power_on(bool on)
2905{
Justin Paupored98328e2011-08-19 13:48:31 -07002906 int rc = on ?
2907 regulator_bulk_enable(ARRAY_SIZE(regs_atmel), regs_atmel) :
2908 regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002909
Justin Paupored98328e2011-08-19 13:48:31 -07002910 if (rc)
2911 pr_err("%s: could not %sable regulators: %d\n",
2912 __func__, on ? "en" : "dis", rc);
2913 else
2914 msleep(50);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002915
Justin Paupored98328e2011-08-19 13:48:31 -07002916 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002917}
2918
2919static int atmel_ts_platform_init(struct i2c_client *client)
2920{
2921 int rc;
Justin Paupored98328e2011-08-19 13:48:31 -07002922 struct device *dev = &client->dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002923
Justin Paupored98328e2011-08-19 13:48:31 -07002924 rc = regulator_bulk_get(dev, ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002925 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002926 dev_err(dev, "%s: could not get regulators: %d\n",
2927 __func__, rc);
2928 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002929 }
2930
Justin Paupored98328e2011-08-19 13:48:31 -07002931 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002932 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002933 dev_err(dev, "%s: could not set voltages: %d\n",
2934 __func__, rc);
2935 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002936 }
2937
2938 rc = gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
2939 GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
2940 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
2941 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002942 dev_err(dev, "%s: gpio_tlmm_config for %d failed\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002943 __func__, ATMEL_TS_GPIO_IRQ);
Justin Paupored98328e2011-08-19 13:48:31 -07002944 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002945 }
2946
2947 /* configure touchscreen interrupt gpio */
2948 rc = gpio_request(ATMEL_TS_GPIO_IRQ, "atmel_maxtouch_gpio");
2949 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002950 dev_err(dev, "%s: unable to request gpio %d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002951 __func__, ATMEL_TS_GPIO_IRQ);
2952 goto ts_gpio_tlmm_unconfig;
2953 }
2954
2955 rc = gpio_direction_input(ATMEL_TS_GPIO_IRQ);
2956 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -07002957 dev_err(dev, "%s: unable to set the direction of gpio %d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002958 __func__, ATMEL_TS_GPIO_IRQ);
2959 goto free_ts_gpio;
2960 }
2961 return 0;
2962
2963free_ts_gpio:
2964 gpio_free(ATMEL_TS_GPIO_IRQ);
2965ts_gpio_tlmm_unconfig:
2966 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
2967 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
2968 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
Justin Paupored98328e2011-08-19 13:48:31 -07002969reg_free:
2970 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
2971out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002972 return rc;
2973}
2974
2975static int atmel_ts_platform_exit(struct i2c_client *client)
2976{
2977 gpio_free(ATMEL_TS_GPIO_IRQ);
2978 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
2979 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
2980 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
Justin Paupored98328e2011-08-19 13:48:31 -07002981 regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
2982 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002983 return 0;
2984}
2985
2986static u8 atmel_ts_read_chg(void)
2987{
2988 return gpio_get_value(ATMEL_TS_GPIO_IRQ);
2989}
2990
2991static u8 atmel_ts_valid_interrupt(void)
2992{
2993 return !atmel_ts_read_chg();
2994}
2995
2996#define ATMEL_X_OFFSET 13
2997#define ATMEL_Y_OFFSET 0
2998
2999static struct mxt_platform_data atmel_ts_pdata = {
3000 .numtouch = 4,
3001 .init_platform_hw = atmel_ts_platform_init,
3002 .exit_platform_hw = atmel_ts_platform_exit,
3003 .power_on = atmel_ts_power_on,
3004 .display_res_x = 480,
3005 .display_res_y = 864,
3006 .min_x = ATMEL_X_OFFSET,
3007 .max_x = (505 - ATMEL_X_OFFSET),
3008 .min_y = ATMEL_Y_OFFSET,
3009 .max_y = (863 - ATMEL_Y_OFFSET),
3010 .valid_interrupt = atmel_ts_valid_interrupt,
3011 .read_chg = atmel_ts_read_chg,
3012};
3013
3014static struct i2c_board_info atmel_ts_i2c_info[] __initdata = {
3015 {
3016 I2C_BOARD_INFO(ATMEL_TS_I2C_NAME, 0x4a),
3017 .platform_data = &atmel_ts_pdata,
3018 .irq = MSM_GPIO_TO_INT(ATMEL_TS_GPIO_IRQ),
3019 },
3020};
3021
3022#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))
3023
3024static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
3025static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
3026
3027static const unsigned short keymap[ARRAY_SIZE(kp_col_gpios) *
3028 ARRAY_SIZE(kp_row_gpios)] = {
3029 [KP_INDEX(0, 0)] = KEY_7,
3030 [KP_INDEX(0, 1)] = KEY_DOWN,
3031 [KP_INDEX(0, 2)] = KEY_UP,
3032 [KP_INDEX(0, 3)] = KEY_RIGHT,
3033 [KP_INDEX(0, 4)] = KEY_ENTER,
3034
3035 [KP_INDEX(1, 0)] = KEY_LEFT,
3036 [KP_INDEX(1, 1)] = KEY_SEND,
3037 [KP_INDEX(1, 2)] = KEY_1,
3038 [KP_INDEX(1, 3)] = KEY_4,
3039 [KP_INDEX(1, 4)] = KEY_CLEAR,
3040
3041 [KP_INDEX(2, 0)] = KEY_6,
3042 [KP_INDEX(2, 1)] = KEY_5,
3043 [KP_INDEX(2, 2)] = KEY_8,
3044 [KP_INDEX(2, 3)] = KEY_3,
3045 [KP_INDEX(2, 4)] = KEY_NUMERIC_STAR,
3046
3047 [KP_INDEX(3, 0)] = KEY_9,
3048 [KP_INDEX(3, 1)] = KEY_NUMERIC_POUND,
3049 [KP_INDEX(3, 2)] = KEY_0,
3050 [KP_INDEX(3, 3)] = KEY_2,
3051 [KP_INDEX(3, 4)] = KEY_SLEEP,
3052
3053 [KP_INDEX(4, 0)] = KEY_BACK,
3054 [KP_INDEX(4, 1)] = KEY_HOME,
3055 [KP_INDEX(4, 2)] = KEY_MENU,
3056 [KP_INDEX(4, 3)] = KEY_VOLUMEUP,
3057 [KP_INDEX(4, 4)] = KEY_VOLUMEDOWN,
3058};
3059
3060/* SURF keypad platform device information */
3061static struct gpio_event_matrix_info kp_matrix_info = {
3062 .info.func = gpio_event_matrix_func,
3063 .keymap = keymap,
3064 .output_gpios = kp_row_gpios,
3065 .input_gpios = kp_col_gpios,
3066 .noutputs = ARRAY_SIZE(kp_row_gpios),
3067 .ninputs = ARRAY_SIZE(kp_col_gpios),
3068 .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
3069 .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
3070 .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
3071 GPIOKPF_PRINT_UNMAPPED_KEYS,
3072};
3073
3074static struct gpio_event_info *kp_info[] = {
3075 &kp_matrix_info.info
3076};
3077
3078static struct gpio_event_platform_data kp_pdata = {
3079 .name = "7x27a_kp",
3080 .info = kp_info,
3081 .info_count = ARRAY_SIZE(kp_info)
3082};
3083
3084static struct platform_device kp_pdev = {
3085 .name = GPIO_EVENT_DEV_NAME,
3086 .id = -1,
3087 .dev = {
3088 .platform_data = &kp_pdata,
3089 },
3090};
3091
3092static struct msm_handset_platform_data hs_platform_data = {
3093 .hs_name = "7k_handset",
3094 .pwr_key_delay_ms = 500, /* 0 will disable end key */
3095};
3096
3097static struct platform_device hs_pdev = {
3098 .name = "msm-handset",
3099 .id = -1,
3100 .dev = {
3101 .platform_data = &hs_platform_data,
3102 },
3103};
3104
Justin Pauporeb3a33b72011-08-23 15:30:32 -07003105static struct platform_device msm_proccomm_regulator_dev = {
3106 .name = PROCCOMM_REGULATOR_DEV_NAME,
3107 .id = -1,
3108 .dev = {
3109 .platform_data = &msm7x27a_proccomm_regulator_data
3110 }
3111};
3112
Trilok Soni16f61af2011-07-26 16:06:58 +05303113static void __init msm7627a_rumi3_init(void)
3114{
3115 msm7x27a_init_ebi2();
3116 platform_add_devices(rumi_sim_devices,
3117 ARRAY_SIZE(rumi_sim_devices));
3118}
3119
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003120#define LED_GPIO_PDM 96
3121#define UART1DM_RX_GPIO 45
Santosh Sajjanb479f0f2011-08-18 21:00:44 +05303122
3123#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
3124static int __init msm7x27a_init_ar6000pm(void)
3125{
3126 return platform_device_register(&msm_wlan_ar6000_pm_device);
3127}
3128#else
3129static int __init msm7x27a_init_ar6000pm(void) { return 0; }
3130#endif
3131
Justin Pauporeb3a33b72011-08-23 15:30:32 -07003132static void __init msm7x27a_init_regulators(void)
3133{
3134 int rc = platform_device_register(&msm_proccomm_regulator_dev);
3135 if (rc)
3136 pr_err("%s: could not register regulator device: %d\n",
3137 __func__, rc);
3138}
3139
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003140static void __init msm7x2x_init(void)
3141{
Trilok Sonia416c492011-07-22 20:20:23 +05303142 msm7x2x_misc_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003143
Justin Pauporeb3a33b72011-08-23 15:30:32 -07003144 /* Initialize regulators first so that other devices can use them */
3145 msm7x27a_init_regulators();
3146
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003147 /* Common functions for SURF/FFA/RUMI3 */
3148 msm_device_i2c_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003149 msm7x27a_init_ebi2();
3150 msm7x27a_cfg_uart2dm_serial();
3151#ifdef CONFIG_SERIAL_MSM_HS
3152 msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
3153 msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
3154#endif
3155
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003156#ifdef CONFIG_USB_MSM_OTG_72K
Trilok Soni16f61af2011-07-26 16:06:58 +05303157 msm_otg_pdata.swfi_latency =
3158 msm7x27a_pm_data
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003159 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
Trilok Soni16f61af2011-07-26 16:06:58 +05303160 msm_device_otg.dev.platform_data = &msm_otg_pdata;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003161#endif
Trilok Soni16f61af2011-07-26 16:06:58 +05303162 msm_device_gadget_peripheral.dev.platform_data =
3163 &msm_gadget_pdata;
3164 msm7x27a_cfg_smsc911x();
3165 platform_add_devices(msm_footswitch_devices,
3166 msm_num_footswitch_devices);
3167 platform_add_devices(surf_ffa_devices,
3168 ARRAY_SIZE(surf_ffa_devices));
Sujith Reddy Thummaad7c9a82011-09-30 20:54:38 +05303169 /* Ensure ar6000pm device is registered before MMC/SDC */
3170 msm7x27a_init_ar6000pm();
3171#ifdef CONFIG_MMC_MSM
3172 msm7x27a_init_mmc();
3173#endif
Trilok Soni16f61af2011-07-26 16:06:58 +05303174 msm_fb_add_devices();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003175#ifdef CONFIG_USB_EHCI_MSM_72K
Trilok Soni16f61af2011-07-26 16:06:58 +05303176 msm7x2x_init_host();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003177#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003178
3179 msm_pm_set_platform_data(msm7x27a_pm_data,
3180 ARRAY_SIZE(msm7x27a_pm_data));
3181
3182#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
3183 register_i2c_devices();
3184#endif
3185#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
3186 bt_power_init();
3187#endif
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303188 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003189 atmel_ts_pdata.min_x = 0;
3190 atmel_ts_pdata.max_x = 480;
3191 atmel_ts_pdata.min_y = 0;
3192 atmel_ts_pdata.max_y = 320;
3193 }
3194
3195 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
3196 atmel_ts_i2c_info,
3197 ARRAY_SIZE(atmel_ts_i2c_info));
3198
Pankaj Kumar5be2a3e2011-09-26 11:45:02 +05303199#if defined(CONFIG_MSM_CAMERA)
Justin Paupored98328e2011-08-19 13:48:31 -07003200 msm_camera_vreg_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003201 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
3202 i2c_camera_devices,
3203 ARRAY_SIZE(i2c_camera_devices));
Pankaj Kumar5be2a3e2011-09-26 11:45:02 +05303204#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003205 platform_device_register(&kp_pdev);
3206 platform_device_register(&hs_pdev);
3207
3208 /* configure it as a pdm function*/
3209 if (gpio_tlmm_config(GPIO_CFG(LED_GPIO_PDM, 3,
3210 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
3211 GPIO_CFG_8MA), GPIO_CFG_ENABLE))
3212 pr_err("%s: gpio_tlmm_config for %d failed\n",
3213 __func__, LED_GPIO_PDM);
3214 else
3215 platform_device_register(&led_pdev);
3216
3217#ifdef CONFIG_MSM_RPC_VIBRATOR
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303218 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003219 msm_init_pmic_vibrator();
3220#endif
3221 /*7x25a kgsl initializations*/
3222 msm7x25a_kgsl_3d0_init();
3223}
3224
3225static void __init msm7x2x_init_early(void)
3226{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003227 msm_msm7x2x_allocate_memory_regions();
3228}
3229
3230MACHINE_START(MSM7X27A_RUMI3, "QCT MSM7x27a RUMI3")
3231 .boot_params = PHYS_OFFSET + 0x100,
3232 .map_io = msm_common_io_init,
3233 .reserve = msm7x27a_reserve,
3234 .init_irq = msm_init_irq,
Trilok Soni16f61af2011-07-26 16:06:58 +05303235 .init_machine = msm7627a_rumi3_init,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003236 .timer = &msm_timer,
3237 .init_early = msm7x2x_init_early,
3238MACHINE_END
3239MACHINE_START(MSM7X27A_SURF, "QCT MSM7x27a SURF")
3240 .boot_params = PHYS_OFFSET + 0x100,
3241 .map_io = msm_common_io_init,
3242 .reserve = msm7x27a_reserve,
3243 .init_irq = msm_init_irq,
3244 .init_machine = msm7x2x_init,
3245 .timer = &msm_timer,
3246 .init_early = msm7x2x_init_early,
3247MACHINE_END
3248MACHINE_START(MSM7X27A_FFA, "QCT MSM7x27a FFA")
3249 .boot_params = PHYS_OFFSET + 0x100,
3250 .map_io = msm_common_io_init,
3251 .reserve = msm7x27a_reserve,
3252 .init_irq = msm_init_irq,
3253 .init_machine = msm7x2x_init,
3254 .timer = &msm_timer,
3255 .init_early = msm7x2x_init_early,
3256MACHINE_END
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303257MACHINE_START(MSM7625A_SURF, "QCT MSM7625a SURF")
3258 .boot_params = PHYS_OFFSET + 0x100,
3259 .map_io = msm_common_io_init,
3260 .reserve = msm7x27a_reserve,
3261 .init_irq = msm_init_irq,
3262 .init_machine = msm7x2x_init,
3263 .timer = &msm_timer,
3264 .init_early = msm7x2x_init_early,
3265MACHINE_END
3266MACHINE_START(MSM7625A_FFA, "QCT MSM7625a FFA")
3267 .boot_params = PHYS_OFFSET + 0x100,
3268 .map_io = msm_common_io_init,
3269 .reserve = msm7x27a_reserve,
3270 .init_irq = msm_init_irq,
3271 .init_machine = msm7x2x_init,
3272 .timer = &msm_timer,
3273 .init_early = msm7x2x_init_early,
3274MACHINE_END