blob: 33a8d423141e1b2ae7a91b918273f51f9791f889 [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>
Maheshkumar Sivasubramanian8ccc16e2011-10-25 15:59:57 -060056#include "pm-boot.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070057
58#define PMEM_KERNEL_EBI1_SIZE 0x3A000
59#define MSM_PMEM_AUDIO_SIZE 0x5B000
60#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
61#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
Rahul Kashyap181d5552011-07-07 10:39:23 +053062#define BAHAMA_SLAVE_ID_FM_REG 0x02
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070063#define FM_GPIO 83
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +053064#define BT_PCM_BCLK_MODE 0x88
65#define BT_PCM_DIN_MODE 0x89
66#define BT_PCM_DOUT_MODE 0x8A
67#define BT_PCM_SYNC_MODE 0x8B
68#define FM_I2S_SD_MODE 0x8E
69#define FM_I2S_WS_MODE 0x8F
70#define FM_I2S_SCK_MODE 0x90
71#define I2C_PIN_CTL 0x15
72#define I2C_NORMAL 0x40
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070073
74enum {
75 GPIO_EXPANDER_IRQ_BASE = NR_MSM_IRQS + NR_GPIO_IRQS,
76 GPIO_EXPANDER_GPIO_BASE = NR_MSM_GPIOS,
77 /* SURF expander */
78 GPIO_CORE_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
79 GPIO_BT_SYS_REST_EN = GPIO_CORE_EXPANDER_BASE,
80 GPIO_WLAN_EXT_POR_N,
81 GPIO_DISPLAY_PWR_EN,
82 GPIO_BACKLIGHT_EN,
83 GPIO_PRESSURE_XCLR,
84 GPIO_VREG_S3_EXP,
85 GPIO_UBM2M_PWRDWN,
86 GPIO_ETM_MODE_CS_N,
87 GPIO_HOST_VBUS_EN,
88 GPIO_SPI_MOSI,
89 GPIO_SPI_MISO,
90 GPIO_SPI_CLK,
91 GPIO_SPI_CS0_N,
92 GPIO_CORE_EXPANDER_IO13,
93 GPIO_CORE_EXPANDER_IO14,
94 GPIO_CORE_EXPANDER_IO15,
95 /* Camera expander */
96 GPIO_CAM_EXPANDER_BASE = GPIO_CORE_EXPANDER_BASE + 16,
97 GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
98 GPIO_CAM_GP_AFBUSY,
99 GPIO_CAM_GP_CAM_PWDN,
100 GPIO_CAM_GP_CAM1MP_XCLR,
101 GPIO_CAM_GP_CAMIF_RESET_N,
102 GPIO_CAM_GP_STROBE_CE,
103 GPIO_CAM_GP_LED_EN1,
104 GPIO_CAM_GP_LED_EN2,
105};
106
107#if defined(CONFIG_GPIO_SX150X)
108enum {
109 SX150X_CORE,
110 SX150X_CAM,
111};
112
113static struct sx150x_platform_data sx150x_data[] __initdata = {
114 [SX150X_CORE] = {
115 .gpio_base = GPIO_CORE_EXPANDER_BASE,
116 .oscio_is_gpo = false,
117 .io_pullup_ena = 0,
pankaj kumarc5c01392011-08-12 13:44:05 +0530118 .io_pulldn_ena = 0x02,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700119 .io_open_drain_ena = 0xfef8,
120 .irq_summary = -1,
121 },
122 [SX150X_CAM] = {
123 .gpio_base = GPIO_CAM_EXPANDER_BASE,
124 .oscio_is_gpo = false,
125 .io_pullup_ena = 0,
126 .io_pulldn_ena = 0,
127 .io_open_drain_ena = 0x23,
128 .irq_summary = -1,
129 },
130};
131#endif
132
133#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
134
135 /* FM Platform power and shutdown routines */
136#define FPGA_MSM_CNTRL_REG2 0x90008010
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530137static int switch_pcm_i2s_reg_mode(int mode)
138{
139 unsigned char reg = 0;
140 int rc = -1;
141 unsigned char set = I2C_PIN_CTL; /*SET PIN CTL mode*/
142 unsigned char unset = I2C_NORMAL; /* UNSET PIN CTL MODE*/
143 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
144
145 if (mode == 0) {
146 /* as we need to switch path to FM we need to move
147 BT AUX PCM lines to PIN CONTROL mode then move
148 FM to normal mode.*/
149 for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
150 rc = marimba_write(&config, reg, &set, 1);
151 if (rc < 0) {
152 pr_err("pcm pinctl failed = %d", rc);
153 goto err_all;
154 }
155 }
156 for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
157 rc = marimba_write(&config, reg, &unset, 1);
158 if (rc < 0) {
159 pr_err("i2s normal failed = %d", rc);
160 goto err_all;
161 }
162 }
163 } else {
164 /* as we need to switch path to AUXPCM we need to move
165 FM I2S lines to PIN CONTROL mode then move
166 BT AUX_PCM to normal mode.*/
167 for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
168 rc = marimba_write(&config, reg, &set, 1);
169 if (rc < 0) {
170 pr_err("i2s pinctl failed = %d", rc);
171 goto err_all;
172 }
173 }
174 for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
175 rc = marimba_write(&config, reg, &unset, 1);
176 if (rc < 0) {
177 pr_err("pcm normal failed = %d", rc);
178 goto err_all;
179 }
180 }
181 }
182
183 return 0;
184
185err_all:
186 return rc;
187}
Rahul Kashyap6e669462011-07-23 16:42:56 +0530188
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700189static void config_pcm_i2s_mode(int mode)
190{
191 void __iomem *cfg_ptr;
192 u8 reg2;
193
194 cfg_ptr = ioremap_nocache(FPGA_MSM_CNTRL_REG2, sizeof(char));
195
196 if (!cfg_ptr)
197 return;
198 if (mode) {
199 /*enable the pcm mode in FPGA*/
200 reg2 = readb_relaxed(cfg_ptr);
201 if (reg2 == 0) {
202 reg2 = 1;
203 writeb_relaxed(reg2, cfg_ptr);
204 }
205 } else {
206 /*enable i2s mode in FPGA*/
207 reg2 = readb_relaxed(cfg_ptr);
208 if (reg2 == 1) {
209 reg2 = 0;
210 writeb_relaxed(reg2, cfg_ptr);
211 }
212 }
213 iounmap(cfg_ptr);
214}
215
216static unsigned fm_i2s_config_power_on[] = {
217 /*FM_I2S_SD*/
218 GPIO_CFG(68, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
219 /*FM_I2S_WS*/
220 GPIO_CFG(70, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
221 /*FM_I2S_SCK*/
222 GPIO_CFG(71, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
223};
224
225static unsigned fm_i2s_config_power_off[] = {
226 /*FM_I2S_SD*/
227 GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
228 /*FM_I2S_WS*/
229 GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
230 /*FM_I2S_SCK*/
231 GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
232};
233
234static unsigned bt_config_power_on[] = {
235 /*RFR*/
236 GPIO_CFG(43, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
237 /*CTS*/
238 GPIO_CFG(44, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
239 /*RX*/
240 GPIO_CFG(45, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
241 /*TX*/
242 GPIO_CFG(46, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
243};
244static unsigned bt_config_pcm_on[] = {
245 /*PCM_DOUT*/
246 GPIO_CFG(68, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
247 /*PCM_DIN*/
248 GPIO_CFG(69, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
249 /*PCM_SYNC*/
250 GPIO_CFG(70, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
251 /*PCM_CLK*/
252 GPIO_CFG(71, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
253};
254static unsigned bt_config_power_off[] = {
255 /*RFR*/
256 GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
257 /*CTS*/
258 GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
259 /*RX*/
260 GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
261 /*TX*/
262 GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
263};
264static unsigned bt_config_pcm_off[] = {
265 /*PCM_DOUT*/
266 GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
267 /*PCM_DIN*/
268 GPIO_CFG(69, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
269 /*PCM_SYNC*/
270 GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
271 /*PCM_CLK*/
272 GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
273};
274
275static int config_i2s(int mode)
276{
277 int pin, rc = 0;
278
279 if (mode == FM_I2S_ON) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +0530280 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700281 config_pcm_i2s_mode(0);
282 pr_err("%s mode = FM_I2S_ON", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530283
284 rc = switch_pcm_i2s_reg_mode(0);
285 if (rc) {
286 pr_err("switch mode failed");
287 return rc;
288 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700289 for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_on);
290 pin++) {
291 rc = gpio_tlmm_config(
292 fm_i2s_config_power_on[pin],
293 GPIO_CFG_ENABLE
294 );
295 if (rc < 0)
296 return rc;
297 }
298 } else if (mode == FM_I2S_OFF) {
299 pr_err("%s mode = FM_I2S_OFF", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530300 rc = switch_pcm_i2s_reg_mode(1);
301 if (rc) {
302 pr_err("switch mode failed");
303 return rc;
304 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700305 for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_off);
306 pin++) {
307 rc = gpio_tlmm_config(
308 fm_i2s_config_power_off[pin],
309 GPIO_CFG_ENABLE
310 );
311 if (rc < 0)
312 return rc;
313 }
314 }
315 return rc;
316}
317static int config_pcm(int mode)
318{
319 int pin, rc = 0;
320
321 if (mode == BT_PCM_ON) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +0530322 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700323 config_pcm_i2s_mode(1);
324 pr_err("%s mode =BT_PCM_ON", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530325 rc = switch_pcm_i2s_reg_mode(1);
326 if (rc) {
327 pr_err("switch mode failed");
328 return rc;
329 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700330 for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
331 pin++) {
332 rc = gpio_tlmm_config(bt_config_pcm_on[pin],
333 GPIO_CFG_ENABLE);
334 if (rc < 0)
335 return rc;
336 }
337 } else if (mode == BT_PCM_OFF) {
338 pr_err("%s mode =BT_PCM_OFF", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530339 rc = switch_pcm_i2s_reg_mode(0);
340 if (rc) {
341 pr_err("switch mode failed");
342 return rc;
343 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700344 for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
345 pin++) {
346 rc = gpio_tlmm_config(bt_config_pcm_off[pin],
347 GPIO_CFG_ENABLE);
348 if (rc < 0)
349 return rc;
350 }
351
352 }
353
354 return rc;
355}
356
357static int msm_bahama_setup_pcm_i2s(int mode)
358{
359 int fm_state = 0, bt_state = 0;
360 int rc = 0;
361 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
362
363 fm_state = marimba_get_fm_status(&config);
364 bt_state = marimba_get_bt_status(&config);
365
366 switch (mode) {
367 case BT_PCM_ON:
368 case BT_PCM_OFF:
369 if (!fm_state)
370 rc = config_pcm(mode);
371 break;
372 case FM_I2S_ON:
373 rc = config_i2s(mode);
374 break;
375 case FM_I2S_OFF:
376 if (bt_state)
377 rc = config_pcm(BT_PCM_ON);
378 else
379 rc = config_i2s(mode);
380 break;
381 default:
382 rc = -EIO;
383 pr_err("%s:Unsupported mode", __func__);
384 }
385 return rc;
386}
387
Rahul Kashyap181d5552011-07-07 10:39:23 +0530388static int bt_set_gpio(int on)
389{
390 int rc = 0;
391 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
392
393 if (on) {
394 rc = gpio_direction_output(GPIO_BT_SYS_REST_EN, 1);
395 msleep(100);
396 } else {
397 if (!marimba_get_fm_status(&config) &&
398 !marimba_get_bt_status(&config)) {
399 gpio_set_value_cansleep(GPIO_BT_SYS_REST_EN, 0);
400 rc = gpio_direction_input(GPIO_BT_SYS_REST_EN);
401 msleep(100);
402 }
403 }
404 if (rc)
405 pr_err("%s: BT sys_reset_en GPIO : Error", __func__);
406
407 return rc;
408}
Justin Paupored98328e2011-08-19 13:48:31 -0700409static struct regulator *fm_regulator;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700410static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
411{
412 int rc = 0;
413 const char *id = "FMPW";
414 uint32_t irqcfg;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530415 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
416 u8 value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700417
418 /* Voting for 1.8V Regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700419 fm_regulator = regulator_get(NULL, "msme1");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700420 if (IS_ERR(fm_regulator)) {
Justin Paupored98328e2011-08-19 13:48:31 -0700421 rc = PTR_ERR(fm_regulator);
422 pr_err("%s: could not get regulator: %d\n", __func__, rc);
423 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700424 }
425
426 /* Set the voltage level to 1.8V */
Justin Paupored98328e2011-08-19 13:48:31 -0700427 rc = regulator_set_voltage(fm_regulator, 1800000, 1800000);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700428 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -0700429 pr_err("%s: could not set voltage: %d\n", __func__, rc);
430 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700431 }
432
433 /* Enabling the 1.8V regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700434 rc = regulator_enable(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700435 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -0700436 pr_err("%s: could not enable regulator: %d\n", __func__, rc);
437 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700438 }
439
440 /* Voting for 19.2MHz clock */
441 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
442 PMAPP_CLOCK_VOTE_ON);
443 if (rc < 0) {
444 pr_err("%s: clock vote failed with :(%d)\n",
445 __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700446 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700447 }
448
Rahul Kashyap181d5552011-07-07 10:39:23 +0530449 rc = bt_set_gpio(1);
450 if (rc) {
451 pr_err("%s: bt_set_gpio = %d", __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700452 goto gpio_deconfig;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530453 }
454 /*re-write FM Slave Id, after reset*/
455 value = BAHAMA_SLAVE_ID_FM_ADDR;
456 rc = marimba_write_bit_mask(&config,
457 BAHAMA_SLAVE_ID_FM_REG, &value, 1, 0xFF);
458 if (rc < 0) {
459 pr_err("%s: FM Slave ID rewrite Failed = %d", __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700460 goto gpio_deconfig;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530461 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700462 /* Configuring the FM GPIO */
463 irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
464 GPIO_CFG_2MA);
465
466 rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE);
467 if (rc) {
468 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
469 __func__, irqcfg, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700470 goto gpio_deconfig;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700471 }
472
473 return 0;
474
Justin Paupored98328e2011-08-19 13:48:31 -0700475gpio_deconfig:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700476 pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
477 PMAPP_CLOCK_VOTE_OFF);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530478 bt_set_gpio(0);
Justin Paupored98328e2011-08-19 13:48:31 -0700479reg_disable:
480 regulator_disable(fm_regulator);
481reg_free:
482 regulator_put(fm_regulator);
483 fm_regulator = NULL;
484out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700485 return rc;
486};
487
488static void fm_radio_shutdown(struct marimba_fm_platform_data *pdata)
489{
490 int rc;
491 const char *id = "FMPW";
492
493 /* Releasing the GPIO line used by FM */
494 uint32_t irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
495 GPIO_CFG_2MA);
496
497 rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE);
498 if (rc)
499 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
500 __func__, irqcfg, rc);
501
502 /* Releasing the 1.8V Regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700503 if (!IS_ERR_OR_NULL(fm_regulator)) {
504 rc = regulator_disable(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700505 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -0700506 pr_err("%s: could not disable regulator: %d\n",
507 __func__, rc);
508 regulator_put(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700509 fm_regulator = NULL;
510 }
511
512 /* Voting off the clock */
513 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
514 PMAPP_CLOCK_VOTE_OFF);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700515 if (rc < 0)
516 pr_err("%s: voting off failed with :(%d)\n",
517 __func__, rc);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530518 rc = bt_set_gpio(0);
519 if (rc)
520 pr_err("%s: bt_set_gpio = %d", __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700521}
522
523static struct marimba_fm_platform_data marimba_fm_pdata = {
524 .fm_setup = fm_radio_setup,
525 .fm_shutdown = fm_radio_shutdown,
526 .irq = MSM_GPIO_TO_INT(FM_GPIO),
527 .vreg_s2 = NULL,
528 .vreg_xo_out = NULL,
529 /* Configuring the FM SoC as I2S Master */
530 .is_fm_soc_i2s_master = true,
531 .config_i2s_gpio = msm_bahama_setup_pcm_i2s,
532};
533
Santosh Sajjan6822c682011-07-26 10:49:36 +0530534static struct platform_device msm_wlan_ar6000_pm_device = {
535 .name = "wlan_ar6000_pm_dev",
536 .id = -1,
537};
538
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700539static struct platform_device msm_bt_power_device = {
540 .name = "bt_power",
541};
Rahul Kashyap6e669462011-07-23 16:42:56 +0530542struct bahama_config_register {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700543 u8 reg;
544 u8 value;
545 u8 mask;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700546};
Rahul Kashyap6e669462011-07-23 16:42:56 +0530547struct bt_vreg_info {
548 const char *name;
549 unsigned int pmapp_id;
Pankaj Kumar6ac59af2011-10-12 12:45:40 +0530550 unsigned int min_level;
551 unsigned int max_level;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530552 unsigned int is_pin_controlled;
Justin Paupored98328e2011-08-19 13:48:31 -0700553 struct regulator *reg;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530554};
555static struct bt_vreg_info bt_vregs[] = {
Pankaj Kumar6ac59af2011-10-12 12:45:40 +0530556 {"msme1", 2, 1800000, 1800000, 0, NULL},
Pankaj Kumarb3edc4f2011-12-08 15:40:29 +0530557 {"bt", 21, 2900000, 3300000, 1, NULL}
Rahul Kashyap6e669462011-07-23 16:42:56 +0530558};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559
560static int bahama_bt(int on)
561{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700562 int rc = 0;
563 int i;
564
565 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
566
567 struct bahama_variant_register {
568 const size_t size;
569 const struct bahama_config_register *set;
570 };
571
572 const struct bahama_config_register *p;
573
574 u8 version;
575
576 const struct bahama_config_register v10_bt_on[] = {
577 { 0xE9, 0x00, 0xFF },
578 { 0xF4, 0x80, 0xFF },
579 { 0xE4, 0x00, 0xFF },
580 { 0xE5, 0x00, 0x0F },
581#ifdef CONFIG_WLAN
582 { 0xE6, 0x38, 0x7F },
583 { 0xE7, 0x06, 0xFF },
584#endif
585 { 0xE9, 0x21, 0xFF },
586 { 0x01, 0x0C, 0x1F },
587 { 0x01, 0x08, 0x1F },
588 };
589
590 const struct bahama_config_register v20_bt_on_fm_off[] = {
591 { 0x11, 0x0C, 0xFF },
592 { 0x13, 0x01, 0xFF },
593 { 0xF4, 0x80, 0xFF },
594 { 0xF0, 0x00, 0xFF },
595 { 0xE9, 0x00, 0xFF },
596#ifdef CONFIG_WLAN
597 { 0x81, 0x00, 0x7F },
598 { 0x82, 0x00, 0xFF },
599 { 0xE6, 0x38, 0x7F },
600 { 0xE7, 0x06, 0xFF },
601#endif
602 { 0x8E, 0x15, 0xFF },
603 { 0x8F, 0x15, 0xFF },
604 { 0x90, 0x15, 0xFF },
605
606 { 0xE9, 0x21, 0xFF },
607 };
608
609 const struct bahama_config_register v20_bt_on_fm_on[] = {
610 { 0x11, 0x0C, 0xFF },
611 { 0x13, 0x01, 0xFF },
612 { 0xF4, 0x86, 0xFF },
613 { 0xF0, 0x06, 0xFF },
614 { 0xE9, 0x00, 0xFF },
615#ifdef CONFIG_WLAN
616 { 0x81, 0x00, 0x7F },
617 { 0x82, 0x00, 0xFF },
618 { 0xE6, 0x38, 0x7F },
619 { 0xE7, 0x06, 0xFF },
620#endif
621 { 0xE9, 0x21, 0xFF },
622 };
623
624 const struct bahama_config_register v10_bt_off[] = {
625 { 0xE9, 0x00, 0xFF },
626 };
627
628 const struct bahama_config_register v20_bt_off_fm_off[] = {
629 { 0xF4, 0x84, 0xFF },
630 { 0xF0, 0x04, 0xFF },
631 { 0xE9, 0x00, 0xFF }
632 };
633
634 const struct bahama_config_register v20_bt_off_fm_on[] = {
635 { 0xF4, 0x86, 0xFF },
636 { 0xF0, 0x06, 0xFF },
637 { 0xE9, 0x00, 0xFF }
638 };
639 const struct bahama_variant_register bt_bahama[2][3] = {
640 {
641 { ARRAY_SIZE(v10_bt_off), v10_bt_off },
642 { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
643 { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
644 },
645 {
646 { ARRAY_SIZE(v10_bt_on), v10_bt_on },
647 { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
648 { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
649 }
650 };
651
652 u8 offset = 0; /* index into bahama configs */
653 on = on ? 1 : 0;
654 version = marimba_read_bahama_ver(&config);
Rahul Kashyap92497af2011-07-07 12:13:52 +0530655 if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
656 dev_err(&msm_bt_power_device.dev, "%s: Bahama \
657 version read Error, version = %d \n",
658 __func__, version);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700659 return -EIO;
660 }
661
662 if (version == BAHAMA_VER_2_0) {
663 if (marimba_get_fm_status(&config))
664 offset = 0x01;
665 }
666
667 p = bt_bahama[on][version + offset].set;
668
669 dev_info(&msm_bt_power_device.dev,
670 "%s: found version %d\n", __func__, version);
671
672 for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
673 u8 value = (p+i)->value;
674 rc = marimba_write_bit_mask(&config,
675 (p+i)->reg,
676 &value,
677 sizeof((p+i)->value),
678 (p+i)->mask);
679 if (rc < 0) {
680 dev_err(&msm_bt_power_device.dev,
681 "%s: reg %x write failed: %d\n",
682 __func__, (p+i)->reg, rc);
683 return rc;
684 }
Rahul Kashyap92497af2011-07-07 12:13:52 +0530685 dev_dbg(&msm_bt_power_device.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700686 "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
687 __func__, (p+i)->reg,
688 value, (p+i)->mask);
689 value = 0;
690 rc = marimba_read_bit_mask(&config,
691 (p+i)->reg, &value,
692 sizeof((p+i)->value), (p+i)->mask);
693 if (rc < 0)
694 dev_err(&msm_bt_power_device.dev, "%s marimba_read_bit_mask- error",
695 __func__);
Rahul Kashyap92497af2011-07-07 12:13:52 +0530696 dev_dbg(&msm_bt_power_device.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700697 "%s: reg 0x%02x read value 0x%02x mask 0x%02x\n",
698 __func__, (p+i)->reg,
699 value, (p+i)->mask);
700 }
701 /* Update BT Status */
702 if (on)
703 marimba_set_bt_status(&config, true);
704 else
705 marimba_set_bt_status(&config, false);
706 return rc;
707}
708static int bluetooth_switch_regulators(int on)
709{
710 int i, rc = 0;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530711 const char *id = "BTPW";
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700712
Rahul Kashyap6e669462011-07-23 16:42:56 +0530713 for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
Justin Paupored98328e2011-08-19 13:48:31 -0700714 if (IS_ERR_OR_NULL(bt_vregs[i].reg)) {
715 rc = bt_vregs[i].reg ?
716 PTR_ERR(bt_vregs[i].reg) :
717 -ENODEV;
718 dev_err(&msm_bt_power_device.dev,
719 "%s: invalid regulator handle for %s: %d\n",
720 __func__, bt_vregs[i].name, rc);
721 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700722 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700723
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530724 rc = on ? regulator_set_voltage(bt_vregs[i].reg,
Pankaj Kumar6ac59af2011-10-12 12:45:40 +0530725 bt_vregs[i].min_level,
726 bt_vregs[i].max_level) : 0;
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530727 if (rc) {
728 dev_err(&msm_bt_power_device.dev,
729 "%s: could not set voltage for %s: %d\n",
730 __func__, bt_vregs[i].name, rc);
731 goto reg_disable;
732 }
733
734 rc = on ? regulator_enable(bt_vregs[i].reg) : 0;
735 if (rc) {
736 dev_err(&msm_bt_power_device.dev,
737 "%s: could not %sable regulator %s: %d\n",
738 __func__, "en", bt_vregs[i].name, rc);
739 goto reg_disable;
740 }
741
Justin Paupored98328e2011-08-19 13:48:31 -0700742 if (bt_vregs[i].is_pin_controlled) {
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530743 rc = pmapp_vreg_lpm_pincntrl_vote(id,
Rahul Kashyap6e669462011-07-23 16:42:56 +0530744 bt_vregs[i].pmapp_id,
745 PMAPP_CLOCK_ID_D1,
746 on ? PMAPP_CLOCK_VOTE_ON :
Justin Paupored98328e2011-08-19 13:48:31 -0700747 PMAPP_CLOCK_VOTE_OFF);
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530748 if (rc) {
749 dev_err(&msm_bt_power_device.dev,
750 "%s: pin control failed for %s: %d\n",
751 __func__, bt_vregs[i].name, rc);
752 goto pin_cnt_fail;
753 }
Rahul Kashyap6e669462011-07-23 16:42:56 +0530754 }
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530755 rc = on ? 0 : regulator_disable(bt_vregs[i].reg);
Justin Paupored98328e2011-08-19 13:48:31 -0700756
757 if (rc) {
758 dev_err(&msm_bt_power_device.dev,
759 "%s: could not %sable regulator %s: %d\n",
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530760 __func__, "dis", bt_vregs[i].name, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700761 goto reg_disable;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530762 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700763 }
Rahul Kashyap6e669462011-07-23 16:42:56 +0530764
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700765 return rc;
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530766pin_cnt_fail:
767 if (on)
768 regulator_disable(bt_vregs[i].reg);
Justin Paupored98328e2011-08-19 13:48:31 -0700769reg_disable:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530770 while (i) {
771 if (on) {
772 i--;
773 regulator_disable(bt_vregs[i].reg);
774 regulator_put(bt_vregs[i].reg);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700775 }
Justin Paupored98328e2011-08-19 13:48:31 -0700776 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700777 return rc;
778}
779
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530780static struct regulator *reg_s3;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700781static unsigned int msm_bahama_setup_power(void)
782{
783 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700784
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530785 reg_s3 = regulator_get(NULL, "msme1");
786 if (IS_ERR(reg_s3)) {
787 rc = PTR_ERR(reg_s3);
Justin Paupored98328e2011-08-19 13:48:31 -0700788 pr_err("%s: could not get regulator: %d\n", __func__, rc);
789 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700790 }
Justin Paupored98328e2011-08-19 13:48:31 -0700791
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530792 rc = regulator_set_voltage(reg_s3, 1800000, 1800000);
Justin Paupored98328e2011-08-19 13:48:31 -0700793 if (rc) {
794 pr_err("%s: could not set voltage: %d\n", __func__, rc);
795 goto reg_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700796 }
Justin Paupored98328e2011-08-19 13:48:31 -0700797
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530798 rc = regulator_enable(reg_s3);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700799 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -0700800 pr_err("%s: could not enable regulator: %d\n", __func__, rc);
801 goto reg_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700802 }
803
804 /*setup Bahama_sys_reset_n*/
805 rc = gpio_request(GPIO_BT_SYS_REST_EN, "bahama sys_rst_n");
Justin Paupored98328e2011-08-19 13:48:31 -0700806 if (rc) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700807 pr_err("%s: gpio_request %d = %d\n", __func__,
808 GPIO_BT_SYS_REST_EN, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700809 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700810 }
Justin Paupored98328e2011-08-19 13:48:31 -0700811
Rahul Kashyap181d5552011-07-07 10:39:23 +0530812 rc = bt_set_gpio(1);
Justin Paupored98328e2011-08-19 13:48:31 -0700813 if (rc) {
Rahul Kashyap181d5552011-07-07 10:39:23 +0530814 pr_err("%s: bt_set_gpio %d = %d\n", __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700815 GPIO_BT_SYS_REST_EN, rc);
816 goto gpio_fail;
817 }
Justin Paupored98328e2011-08-19 13:48:31 -0700818
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700819 return rc;
820
821gpio_fail:
822 gpio_free(GPIO_BT_SYS_REST_EN);
Justin Paupored98328e2011-08-19 13:48:31 -0700823reg_disable:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530824 regulator_disable(reg_s3);
Justin Paupored98328e2011-08-19 13:48:31 -0700825reg_fail:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530826 regulator_put(reg_s3);
Justin Paupored98328e2011-08-19 13:48:31 -0700827out:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530828 reg_s3 = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700829 return rc;
830}
831
832static unsigned int msm_bahama_shutdown_power(int value)
833{
834 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700835
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530836 if (IS_ERR_OR_NULL(reg_s3)) {
837 rc = reg_s3 ? PTR_ERR(reg_s3) : -ENODEV;
Justin Paupored98328e2011-08-19 13:48:31 -0700838 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700839 }
Justin Paupored98328e2011-08-19 13:48:31 -0700840
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530841 rc = regulator_disable(reg_s3);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700842 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -0700843 pr_err("%s: could not disable regulator: %d\n", __func__, rc);
844 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700845 }
Justin Paupored98328e2011-08-19 13:48:31 -0700846
Rahul Kashyape8698c62011-07-20 20:43:05 +0530847 if (value == BAHAMA_ID) {
848 rc = bt_set_gpio(0);
849 if (rc) {
850 pr_err("%s: bt_set_gpio = %d\n",
851 __func__, rc);
852 }
Justin Paupored98328e2011-08-19 13:48:31 -0700853 gpio_free(GPIO_BT_SYS_REST_EN);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530854 }
Justin Paupored98328e2011-08-19 13:48:31 -0700855
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530856 regulator_put(reg_s3);
857 reg_s3 = NULL;
Justin Paupored98328e2011-08-19 13:48:31 -0700858
859 return 0;
860
Justin Paupored98328e2011-08-19 13:48:31 -0700861out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700862 return rc;
863}
864
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700865static unsigned int msm_bahama_core_config(int type)
866{
867 int rc = 0;
868
869 if (type == BAHAMA_ID) {
870 int i;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530871 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700872 const struct bahama_config_register v20_init[] = {
873 /* reg, value, mask */
874 { 0xF4, 0x84, 0xFF }, /* AREG */
875 { 0xF0, 0x04, 0xFF } /* DREG */
876 };
877 if (marimba_read_bahama_ver(&config) == BAHAMA_VER_2_0) {
878 for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
879 u8 value = v20_init[i].value;
880 rc = marimba_write_bit_mask(&config,
881 v20_init[i].reg,
882 &value,
883 sizeof(v20_init[i].value),
884 v20_init[i].mask);
885 if (rc < 0) {
886 pr_err("%s: reg %d write failed: %d\n",
887 __func__, v20_init[i].reg, rc);
888 return rc;
889 }
890 pr_debug("%s: reg 0x%02x value 0x%02x"
891 " mask 0x%02x\n",
892 __func__, v20_init[i].reg,
893 v20_init[i].value, v20_init[i].mask);
894 }
895 }
896 }
Rahul Kashyap181d5552011-07-07 10:39:23 +0530897 rc = bt_set_gpio(0);
898 if (rc) {
899 pr_err("%s: bt_set_gpio = %d\n",
900 __func__, rc);
901 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700902 pr_debug("core type: %d\n", type);
903 return rc;
904}
905
906static int bluetooth_power(int on)
907{
908 int pin, rc = 0;
909 const char *id = "BTPW";
910 int cid = 0;
911
912 cid = adie_get_detected_connectivity_type();
913 if (cid != BAHAMA_ID) {
914 pr_err("%s: unexpected adie connectivity type: %d\n",
915 __func__, cid);
916 return -ENODEV;
917 }
918 if (on) {
919 /*setup power for BT SOC*/
Rahul Kashyap181d5552011-07-07 10:39:23 +0530920 rc = bt_set_gpio(on);
921 if (rc) {
922 pr_err("%s: bt_set_gpio = %d\n",
923 __func__, rc);
924 goto exit;
925 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700926 rc = bluetooth_switch_regulators(on);
927 if (rc < 0) {
928 pr_err("%s: bluetooth_switch_regulators rc = %d",
929 __func__, rc);
930 goto exit;
931 }
932 /*setup BT GPIO lines*/
933 for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on);
934 pin++) {
935 rc = gpio_tlmm_config(bt_config_power_on[pin],
936 GPIO_CFG_ENABLE);
937 if (rc < 0) {
938 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
939 __func__,
940 bt_config_power_on[pin],
941 rc);
942 goto fail_power;
943 }
944 }
945 /*Setup BT clocks*/
946 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
947 PMAPP_CLOCK_VOTE_ON);
948 if (rc < 0) {
949 pr_err("Failed to vote for TCXO_D1 ON\n");
950 goto fail_clock;
951 }
952 msleep(20);
953
954 /*I2C config for Bahama*/
955 rc = bahama_bt(1);
956 if (rc < 0) {
957 pr_err("%s: bahama_bt rc = %d", __func__, rc);
958 goto fail_i2c;
959 }
960 msleep(20);
961
962 /*setup BT PCM lines*/
963 rc = msm_bahama_setup_pcm_i2s(BT_PCM_ON);
964 if (rc < 0) {
965 pr_err("%s: msm_bahama_setup_pcm_i2s , rc =%d\n",
966 __func__, rc);
967 goto fail_power;
968 }
969 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
970 PMAPP_CLOCK_VOTE_PIN_CTRL);
971 if (rc < 0)
972 pr_err("%s:Pin Control Failed, rc = %d",
973 __func__, rc);
974
975 } else {
976 rc = bahama_bt(0);
977 if (rc < 0)
978 pr_err("%s: bahama_bt rc = %d", __func__, rc);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530979
980 rc = bt_set_gpio(on);
981 if (rc) {
982 pr_err("%s: bt_set_gpio = %d\n",
983 __func__, rc);
984 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700985fail_i2c:
986 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
987 PMAPP_CLOCK_VOTE_OFF);
988 if (rc < 0)
989 pr_err("%s: Failed to vote Off D1\n", __func__);
990fail_clock:
991 for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off);
992 pin++) {
993 rc = gpio_tlmm_config(bt_config_power_off[pin],
994 GPIO_CFG_ENABLE);
995 if (rc < 0) {
996 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
997 __func__, bt_config_power_off[pin], rc);
998 }
999 }
1000 rc = msm_bahama_setup_pcm_i2s(BT_PCM_OFF);
1001 if (rc < 0) {
1002 pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
1003 __func__, rc);
1004 }
1005fail_power:
1006 rc = bluetooth_switch_regulators(0);
1007 if (rc < 0) {
1008 pr_err("%s: switch_regulators : rc = %d",\
1009 __func__, rc);
1010 goto exit;
1011 }
1012 }
1013 return rc;
1014exit:
1015 pr_err("%s: failed with rc = %d", __func__, rc);
1016 return rc;
1017}
1018
1019static int __init bt_power_init(void)
1020{
1021 int i, rc = 0;
Justin Paupored98328e2011-08-19 13:48:31 -07001022 struct device *dev = &msm_bt_power_device.dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001023
Justin Paupored98328e2011-08-19 13:48:31 -07001024 for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
1025 bt_vregs[i].reg = regulator_get(dev, bt_vregs[i].name);
1026 if (IS_ERR(bt_vregs[i].reg)) {
1027 rc = PTR_ERR(bt_vregs[i].reg);
1028 dev_err(dev, "%s: could not get regulator %s: %d\n",
1029 __func__, bt_vregs[i].name, rc);
1030 goto reg_get_fail;
1031 }
Justin Paupored98328e2011-08-19 13:48:31 -07001032 }
1033
1034 dev->platform_data = &bluetooth_power;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001035
1036 return rc;
1037
Justin Paupored98328e2011-08-19 13:48:31 -07001038reg_get_fail:
1039 while (i--) {
1040 regulator_put(bt_vregs[i].reg);
1041 bt_vregs[i].reg = NULL;
1042 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001043 return rc;
1044}
1045
1046static struct marimba_platform_data marimba_pdata = {
1047 .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,
1048 .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
1049 .bahama_setup = msm_bahama_setup_power,
1050 .bahama_shutdown = msm_bahama_shutdown_power,
1051 .bahama_core_config = msm_bahama_core_config,
1052 .fm = &marimba_fm_pdata,
1053};
1054
1055#endif
1056
1057#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
1058static struct i2c_board_info core_exp_i2c_info[] __initdata = {
1059 {
1060 I2C_BOARD_INFO("sx1509q", 0x3e),
1061 },
1062};
1063static struct i2c_board_info cam_exp_i2c_info[] __initdata = {
1064 {
1065 I2C_BOARD_INFO("sx1508q", 0x22),
1066 .platform_data = &sx150x_data[SX150X_CAM],
1067 },
1068};
1069#endif
1070#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
1071static struct i2c_board_info bahama_devices[] = {
1072{
1073 I2C_BOARD_INFO("marimba", 0xc),
1074 .platform_data = &marimba_pdata,
1075},
1076};
1077#endif
1078
1079#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
1080static void __init register_i2c_devices(void)
1081{
1082
1083 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
1084 cam_exp_i2c_info,
1085 ARRAY_SIZE(cam_exp_i2c_info));
1086
Trilok Soni3d0f6c52011-07-26 16:06:58 +05301087 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001088 sx150x_data[SX150X_CORE].io_open_drain_ena = 0xe0f0;
1089
1090 core_exp_i2c_info[0].platform_data =
1091 &sx150x_data[SX150X_CORE];
1092
1093 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
1094 core_exp_i2c_info,
1095 ARRAY_SIZE(core_exp_i2c_info));
1096#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
1097 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
1098 bahama_devices,
1099 ARRAY_SIZE(bahama_devices));
1100#endif
1101}
1102#endif
1103
1104static struct msm_gpio qup_i2c_gpios_io[] = {
1105 { GPIO_CFG(60, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1106 "qup_scl" },
1107 { GPIO_CFG(61, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1108 "qup_sda" },
1109 { GPIO_CFG(131, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1110 "qup_scl" },
1111 { GPIO_CFG(132, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1112 "qup_sda" },
1113};
1114
1115static struct msm_gpio qup_i2c_gpios_hw[] = {
1116 { GPIO_CFG(60, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1117 "qup_scl" },
1118 { GPIO_CFG(61, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1119 "qup_sda" },
1120 { GPIO_CFG(131, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1121 "qup_scl" },
1122 { GPIO_CFG(132, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1123 "qup_sda" },
1124};
1125
1126static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
1127{
1128 int rc;
1129
1130 if (adap_id < 0 || adap_id > 1)
1131 return;
1132
1133 /* Each adapter gets 2 lines from the table */
1134 if (config_type)
1135 rc = msm_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
1136 else
1137 rc = msm_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
1138 if (rc < 0)
1139 pr_err("QUP GPIO request/enable failed: %d\n", rc);
1140}
1141
1142static struct msm_i2c_platform_data msm_gsbi0_qup_i2c_pdata = {
1143 .clk_freq = 100000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001144 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
1145};
1146
1147static struct msm_i2c_platform_data msm_gsbi1_qup_i2c_pdata = {
1148 .clk_freq = 100000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001149 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
1150};
1151
1152#ifdef CONFIG_ARCH_MSM7X27A
Neti Ravi Kumar061726e2011-12-08 15:14:57 +05301153#define MSM_PMEM_MDP_SIZE 0x2300000
1154#define MSM7x25A_MSM_PMEM_MDP_SIZE 0x1500000
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301155
Roja Rani Yarubandi09986562011-12-06 18:54:47 +05301156#define MSM_PMEM_ADSP_SIZE 0x1000000
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301157#define MSM7x25A_MSM_PMEM_ADSP_SIZE 0xB91000
1158
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001159
1160#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301161#define MSM_FB_SIZE 0x260000
1162#define MSM7x25A_MSM_FB_SIZE 0xE1000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001163#else
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301164#define MSM_FB_SIZE 0x195000
1165#define MSM7x25A_MSM_FB_SIZE 0xE1000
1166
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001167#endif
1168
1169#endif
1170
1171static struct android_usb_platform_data android_usb_pdata = {
1172 .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
1173};
1174
1175static struct platform_device android_usb_device = {
1176 .name = "android_usb",
1177 .id = -1,
1178 .dev = {
1179 .platform_data = &android_usb_pdata,
1180 },
1181};
1182
1183#ifdef CONFIG_USB_EHCI_MSM_72K
1184static void msm_hsusb_vbus_power(unsigned phy_info, int on)
1185{
1186 int rc = 0;
1187 unsigned gpio;
1188
1189 gpio = GPIO_HOST_VBUS_EN;
1190
1191 rc = gpio_request(gpio, "i2c_host_vbus_en");
1192 if (rc < 0) {
1193 pr_err("failed to request %d GPIO\n", gpio);
1194 return;
1195 }
1196 gpio_direction_output(gpio, !!on);
1197 gpio_set_value_cansleep(gpio, !!on);
1198 gpio_free(gpio);
1199}
1200
1201static struct msm_usb_host_platform_data msm_usb_host_pdata = {
1202 .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_45NM),
1203};
1204
1205static void __init msm7x2x_init_host(void)
1206{
1207 msm_add_host(0, &msm_usb_host_pdata);
1208}
1209#endif
1210
1211#ifdef CONFIG_USB_MSM_OTG_72K
1212static int hsusb_rpc_connect(int connect)
1213{
1214 if (connect)
1215 return msm_hsusb_rpc_connect();
1216 else
1217 return msm_hsusb_rpc_close();
1218}
1219
Justin Paupored98328e2011-08-19 13:48:31 -07001220static struct regulator *reg_hsusb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001221static int msm_hsusb_ldo_init(int init)
1222{
Justin Paupored98328e2011-08-19 13:48:31 -07001223 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001224
Justin Paupored98328e2011-08-19 13:48:31 -07001225 if (init) {
1226 reg_hsusb = regulator_get(NULL, "usb");
1227 if (IS_ERR(reg_hsusb)) {
1228 rc = PTR_ERR(reg_hsusb);
1229 pr_err("%s: could not get regulator: %d\n",
1230 __func__, rc);
1231 goto out;
1232 }
1233
1234 rc = regulator_set_voltage(reg_hsusb, 3300000, 3300000);
1235 if (rc) {
1236 pr_err("%s: could not set voltage: %d\n",
1237 __func__, rc);
1238 goto reg_free;
1239 }
1240
1241 return 0;
1242 }
1243 /* else fall through */
1244reg_free:
1245 regulator_put(reg_hsusb);
1246out:
1247 reg_hsusb = NULL;
1248 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001249}
1250
1251static int msm_hsusb_ldo_enable(int enable)
1252{
1253 static int ldo_status;
1254
Justin Paupored98328e2011-08-19 13:48:31 -07001255 if (IS_ERR_OR_NULL(reg_hsusb))
1256 return reg_hsusb ? PTR_ERR(reg_hsusb) : -ENODEV;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001257
1258 if (ldo_status == enable)
1259 return 0;
1260
1261 ldo_status = enable;
1262
Justin Paupored98328e2011-08-19 13:48:31 -07001263 return enable ?
1264 regulator_enable(reg_hsusb) :
1265 regulator_disable(reg_hsusb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001266}
1267
1268#ifndef CONFIG_USB_EHCI_MSM_72K
1269static int msm_hsusb_pmic_notif_init(void (*callback)(int online), int init)
1270{
1271 int ret = 0;
1272
1273 if (init)
1274 ret = msm_pm_app_rpc_init(callback);
1275 else
1276 msm_pm_app_rpc_deinit(callback);
1277
1278 return ret;
1279}
1280#endif
1281
1282static struct msm_otg_platform_data msm_otg_pdata = {
1283#ifndef CONFIG_USB_EHCI_MSM_72K
1284 .pmic_vbus_notif_init = msm_hsusb_pmic_notif_init,
1285#else
1286 .vbus_power = msm_hsusb_vbus_power,
1287#endif
1288 .rpc_connect = hsusb_rpc_connect,
1289 .core_clk = 1,
1290 .pemp_level = PRE_EMPHASIS_WITH_20_PERCENT,
1291 .cdr_autoreset = CDR_AUTO_RESET_DISABLE,
1292 .drv_ampl = HS_DRV_AMPLITUDE_DEFAULT,
1293 .se1_gating = SE1_GATING_DISABLE,
1294 .ldo_init = msm_hsusb_ldo_init,
1295 .ldo_enable = msm_hsusb_ldo_enable,
1296 .chg_init = hsusb_chg_init,
1297 .chg_connected = hsusb_chg_connected,
1298 .chg_vbus_draw = hsusb_chg_vbus_draw,
1299};
1300#endif
1301
1302static struct msm_hsusb_gadget_platform_data msm_gadget_pdata = {
1303 .is_phy_status_timer_on = 1,
1304};
1305
1306static struct resource smc91x_resources[] = {
1307 [0] = {
1308 .start = 0x90000300,
1309 .end = 0x900003ff,
1310 .flags = IORESOURCE_MEM,
1311 },
1312 [1] = {
1313 .start = MSM_GPIO_TO_INT(4),
1314 .end = MSM_GPIO_TO_INT(4),
1315 .flags = IORESOURCE_IRQ,
1316 },
1317};
1318
1319static struct platform_device smc91x_device = {
1320 .name = "smc91x",
1321 .id = 0,
1322 .num_resources = ARRAY_SIZE(smc91x_resources),
1323 .resource = smc91x_resources,
1324};
1325
1326#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT)\
1327 || defined(CONFIG_MMC_MSM_SDC2_SUPPORT)\
1328 || defined(CONFIG_MMC_MSM_SDC3_SUPPORT)\
1329 || defined(CONFIG_MMC_MSM_SDC4_SUPPORT))
1330
1331static unsigned long vreg_sts, gpio_sts;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001332
1333struct sdcc_gpio {
1334 struct msm_gpio *cfg_data;
1335 uint32_t size;
1336 struct msm_gpio *sleep_cfg_data;
1337};
1338
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301339/**
1340 * Due to insufficient drive strengths for SDC GPIO lines some old versioned
1341 * SD/MMC cards may cause data CRC errors. Hence, set optimal values
1342 * for SDC slots based on timing closure and marginality. SDC1 slot
1343 * require higher value since it should handle bad signal quality due
1344 * to size of T-flash adapters.
1345 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001346static struct msm_gpio sdc1_cfg_data[] = {
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301347 {GPIO_CFG(51, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001348 "sdc1_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301349 {GPIO_CFG(52, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001350 "sdc1_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301351 {GPIO_CFG(53, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001352 "sdc1_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301353 {GPIO_CFG(54, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001354 "sdc1_dat_0"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301355 {GPIO_CFG(55, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001356 "sdc1_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301357 {GPIO_CFG(56, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_14MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001358 "sdc1_clk"},
1359};
1360
1361static struct msm_gpio sdc2_cfg_data[] = {
1362 {GPIO_CFG(62, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1363 "sdc2_clk"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301364 {GPIO_CFG(63, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001365 "sdc2_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301366 {GPIO_CFG(64, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001367 "sdc2_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301368 {GPIO_CFG(65, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001369 "sdc2_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301370 {GPIO_CFG(66, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001371 "sdc2_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301372 {GPIO_CFG(67, 2, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001373 "sdc2_dat_0"},
1374};
1375
1376static struct msm_gpio sdc2_sleep_cfg_data[] = {
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301377 {GPIO_CFG(62, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001378 "sdc2_clk"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301379 {GPIO_CFG(63, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001380 "sdc2_cmd"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301381 {GPIO_CFG(64, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001382 "sdc2_dat_3"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301383 {GPIO_CFG(65, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001384 "sdc2_dat_2"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301385 {GPIO_CFG(66, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001386 "sdc2_dat_1"},
Sujith Reddy Thummaf3535672011-08-22 08:53:44 +05301387 {GPIO_CFG(67, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001388 "sdc2_dat_0"},
1389};
1390static struct msm_gpio sdc3_cfg_data[] = {
1391 {GPIO_CFG(88, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1392 "sdc3_clk"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301393 {GPIO_CFG(89, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001394 "sdc3_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301395 {GPIO_CFG(90, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001396 "sdc3_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301397 {GPIO_CFG(91, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001398 "sdc3_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301399 {GPIO_CFG(92, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001400 "sdc3_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301401 {GPIO_CFG(93, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001402 "sdc3_dat_0"},
1403#ifdef CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301404 {GPIO_CFG(19, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001405 "sdc3_dat_7"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301406 {GPIO_CFG(20, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001407 "sdc3_dat_6"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301408 {GPIO_CFG(21, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001409 "sdc3_dat_5"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301410 {GPIO_CFG(108, 3, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001411 "sdc3_dat_4"},
1412#endif
1413};
1414
1415static struct msm_gpio sdc4_cfg_data[] = {
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301416 {GPIO_CFG(19, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001417 "sdc4_dat_3"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301418 {GPIO_CFG(20, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001419 "sdc4_dat_2"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301420 {GPIO_CFG(21, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001421 "sdc4_dat_1"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301422 {GPIO_CFG(107, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001423 "sdc4_cmd"},
Sujith Reddy Thumma70391a32011-08-01 10:33:21 +05301424 {GPIO_CFG(108, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_10MA),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001425 "sdc4_dat_0"},
1426 {GPIO_CFG(109, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1427 "sdc4_clk"},
1428};
1429
1430static struct sdcc_gpio sdcc_cfg_data[] = {
1431 {
1432 .cfg_data = sdc1_cfg_data,
1433 .size = ARRAY_SIZE(sdc1_cfg_data),
1434 },
1435 {
1436 .cfg_data = sdc2_cfg_data,
1437 .size = ARRAY_SIZE(sdc2_cfg_data),
1438 .sleep_cfg_data = sdc2_sleep_cfg_data,
1439 },
1440 {
1441 .cfg_data = sdc3_cfg_data,
1442 .size = ARRAY_SIZE(sdc3_cfg_data),
1443 },
1444 {
1445 .cfg_data = sdc4_cfg_data,
1446 .size = ARRAY_SIZE(sdc4_cfg_data),
1447 },
1448};
1449
Justin Paupored98328e2011-08-19 13:48:31 -07001450static struct regulator *sdcc_vreg_data[ARRAY_SIZE(sdcc_cfg_data)];
1451
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001452static int msm_sdcc_setup_gpio(int dev_id, unsigned int enable)
1453{
1454 int rc = 0;
1455 struct sdcc_gpio *curr;
1456
1457 curr = &sdcc_cfg_data[dev_id - 1];
1458 if (!(test_bit(dev_id, &gpio_sts)^enable))
1459 return rc;
1460
1461 if (enable) {
1462 set_bit(dev_id, &gpio_sts);
1463 rc = msm_gpios_request_enable(curr->cfg_data, curr->size);
1464 if (rc)
1465 pr_err("%s: Failed to turn on GPIOs for slot %d\n",
1466 __func__, dev_id);
1467 } else {
1468 clear_bit(dev_id, &gpio_sts);
1469 if (curr->sleep_cfg_data) {
1470 rc = msm_gpios_enable(curr->sleep_cfg_data, curr->size);
1471 msm_gpios_free(curr->sleep_cfg_data, curr->size);
1472 return rc;
1473 }
1474 msm_gpios_disable_free(curr->cfg_data, curr->size);
1475 }
1476 return rc;
1477}
1478
1479static int msm_sdcc_setup_vreg(int dev_id, unsigned int enable)
1480{
1481 int rc = 0;
Justin Paupored98328e2011-08-19 13:48:31 -07001482 struct regulator *curr = sdcc_vreg_data[dev_id - 1];
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001483
Justin Paupored98328e2011-08-19 13:48:31 -07001484 if (test_bit(dev_id, &vreg_sts) == enable)
1485 return 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001486
Justin Paupored98328e2011-08-19 13:48:31 -07001487 if (!curr)
1488 return -ENODEV;
1489
1490 if (IS_ERR(curr))
1491 return PTR_ERR(curr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001492
1493 if (enable) {
1494 set_bit(dev_id, &vreg_sts);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001495
Justin Paupored98328e2011-08-19 13:48:31 -07001496 rc = regulator_enable(curr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001497 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -07001498 pr_err("%s: could not enable regulator: %d\n",
1499 __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001500 } else {
1501 clear_bit(dev_id, &vreg_sts);
Justin Paupored98328e2011-08-19 13:48:31 -07001502
1503 rc = regulator_disable(curr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001504 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -07001505 pr_err("%s: could not disable regulator: %d\n",
1506 __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001507 }
1508 return rc;
1509}
1510
1511static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
1512{
1513 int rc = 0;
1514 struct platform_device *pdev;
1515
1516 pdev = container_of(dv, struct platform_device, dev);
1517
1518 rc = msm_sdcc_setup_gpio(pdev->id, !!vdd);
1519 if (rc)
1520 goto out;
1521
1522 rc = msm_sdcc_setup_vreg(pdev->id, !!vdd);
1523out:
1524 return rc;
1525}
1526
1527#define GPIO_SDC1_HW_DET 85
1528
1529#if defined(CONFIG_MMC_MSM_SDC1_SUPPORT) \
1530 && defined(CONFIG_MMC_MSM_CARD_HW_DETECTION)
1531static unsigned int msm7x2xa_sdcc_slot_status(struct device *dev)
1532{
1533 int status;
1534
1535 status = gpio_tlmm_config(GPIO_CFG(GPIO_SDC1_HW_DET, 2, GPIO_CFG_INPUT,
1536 GPIO_CFG_PULL_UP, GPIO_CFG_8MA), GPIO_CFG_ENABLE);
1537 if (status)
1538 pr_err("%s:Failed to configure tlmm for GPIO %d\n", __func__,
1539 GPIO_SDC1_HW_DET);
1540
1541 status = gpio_request(GPIO_SDC1_HW_DET, "SD_HW_Detect");
1542 if (status) {
1543 pr_err("%s:Failed to request GPIO %d\n", __func__,
1544 GPIO_SDC1_HW_DET);
1545 } else {
1546 status = gpio_direction_input(GPIO_SDC1_HW_DET);
1547 if (!status)
1548 status = gpio_get_value(GPIO_SDC1_HW_DET);
1549 gpio_free(GPIO_SDC1_HW_DET);
1550 }
1551 return status;
1552}
1553#endif
1554
1555#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
1556static struct mmc_platform_data sdc1_plat_data = {
1557 .ocr_mask = MMC_VDD_28_29,
1558 .translate_vdd = msm_sdcc_setup_power,
1559 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1560 .msmsdcc_fmin = 144000,
1561 .msmsdcc_fmid = 24576000,
1562 .msmsdcc_fmax = 49152000,
1563#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
1564 .status = msm7x2xa_sdcc_slot_status,
1565 .status_irq = MSM_GPIO_TO_INT(GPIO_SDC1_HW_DET),
1566 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
1567#endif
1568};
1569#endif
1570
1571#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
1572static struct mmc_platform_data sdc2_plat_data = {
1573 /*
1574 * SDC2 supports only 1.8V, claim for 2.85V range is just
1575 * for allowing buggy cards who advertise 2.8V even though
1576 * they can operate at 1.8V supply.
1577 */
1578 .ocr_mask = MMC_VDD_28_29 | MMC_VDD_165_195,
1579 .translate_vdd = msm_sdcc_setup_power,
1580 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1581#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
1582 .sdiowakeup_irq = MSM_GPIO_TO_INT(66),
1583#endif
1584 .msmsdcc_fmin = 144000,
1585 .msmsdcc_fmid = 24576000,
1586 .msmsdcc_fmax = 49152000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001587};
1588#endif
1589
1590#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
1591static struct mmc_platform_data sdc3_plat_data = {
1592 .ocr_mask = MMC_VDD_28_29,
1593 .translate_vdd = msm_sdcc_setup_power,
1594#ifdef CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT
1595 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
1596#else
1597 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1598#endif
1599 .msmsdcc_fmin = 144000,
1600 .msmsdcc_fmid = 24576000,
1601 .msmsdcc_fmax = 49152000,
1602 .nonremovable = 1,
1603};
1604#endif
1605
1606#if (defined(CONFIG_MMC_MSM_SDC4_SUPPORT)\
1607 && !defined(CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT))
1608static struct mmc_platform_data sdc4_plat_data = {
1609 .ocr_mask = MMC_VDD_28_29,
1610 .translate_vdd = msm_sdcc_setup_power,
1611 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
1612 .msmsdcc_fmin = 144000,
1613 .msmsdcc_fmid = 24576000,
1614 .msmsdcc_fmax = 49152000,
1615};
1616#endif
Pankaj Kumarb3e55c62011-09-26 11:59:39 +05301617
1618static int __init mmc_regulator_init(int sdcc_no, const char *supply, int uV)
1619{
1620 int rc;
1621
1622 BUG_ON(sdcc_no < 1 || sdcc_no > 4);
1623
1624 sdcc_no--;
1625
1626 sdcc_vreg_data[sdcc_no] = regulator_get(NULL, supply);
1627
1628 if (IS_ERR(sdcc_vreg_data[sdcc_no])) {
1629 rc = PTR_ERR(sdcc_vreg_data[sdcc_no]);
1630 pr_err("%s: could not get regulator \"%s\": %d\n",
1631 __func__, supply, rc);
1632 goto out;
1633 }
1634
1635 rc = regulator_set_voltage(sdcc_vreg_data[sdcc_no], uV, uV);
1636
1637 if (rc) {
1638 pr_err("%s: could not set voltage for \"%s\" to %d uV: %d\n",
1639 __func__, supply, uV, rc);
1640 goto reg_free;
1641 }
1642
1643 return rc;
1644
1645reg_free:
1646 regulator_put(sdcc_vreg_data[sdcc_no]);
1647out:
1648 sdcc_vreg_data[sdcc_no] = NULL;
1649 return rc;
1650}
1651
1652static void __init msm7x27a_init_mmc(void)
1653{
1654 /* eMMC slot */
1655#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
1656 if (mmc_regulator_init(3, "emmc", 3000000))
1657 return;
1658 msm_add_sdcc(3, &sdc3_plat_data);
1659#endif
1660 /* Micro-SD slot */
1661#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
1662 if (mmc_regulator_init(1, "mmc", 2850000))
1663 return;
1664 msm_add_sdcc(1, &sdc1_plat_data);
1665#endif
1666 /* SDIO WLAN slot */
1667#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
1668 if (mmc_regulator_init(2, "mmc", 2850000))
1669 return;
1670 msm_add_sdcc(2, &sdc2_plat_data);
1671#endif
1672 /* Not Used */
1673#if (defined(CONFIG_MMC_MSM_SDC4_SUPPORT)\
1674 && !defined(CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT))
1675 if (mmc_regulator_init(4, "mmc", 2850000))
1676 return;
1677 msm_add_sdcc(4, &sdc4_plat_data);
1678#endif
1679}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001680#endif
1681
1682#ifdef CONFIG_SERIAL_MSM_HS
1683static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = {
1684 .inject_rx_on_wakeup = 1,
1685 .rx_to_inject = 0xFD,
1686};
1687#endif
1688static struct msm_pm_platform_data msm7x27a_pm_data[MSM_PM_SLEEP_MODE_NR] = {
1689 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
1690 .idle_supported = 1,
1691 .suspend_supported = 1,
1692 .idle_enabled = 1,
1693 .suspend_enabled = 1,
1694 .latency = 16000,
1695 .residency = 20000,
1696 },
1697 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
1698 .idle_supported = 1,
1699 .suspend_supported = 1,
1700 .idle_enabled = 1,
1701 .suspend_enabled = 1,
1702 .latency = 12000,
1703 .residency = 20000,
1704 },
1705 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
1706 .idle_supported = 1,
1707 .suspend_supported = 1,
1708 .idle_enabled = 0,
1709 .suspend_enabled = 1,
1710 .latency = 2000,
1711 .residency = 0,
1712 },
1713 [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
1714 .idle_supported = 1,
1715 .suspend_supported = 1,
1716 .idle_enabled = 1,
1717 .suspend_enabled = 1,
1718 .latency = 2,
1719 .residency = 0,
1720 },
1721};
1722
Maheshkumar Sivasubramanianc6c55032011-10-25 16:01:32 -06001723static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = {
1724 .mode = MSM_PM_BOOT_CONFIG_RESET_VECTOR_VIRT,
1725 .v_addr = (uint32_t *)PAGE_OFFSET,
1726};
1727
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001728static struct android_pmem_platform_data android_pmem_adsp_pdata = {
1729 .name = "pmem_adsp",
1730 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
Mahesh Lankac6af7eb2011-08-02 18:00:35 +05301731 .cached = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001732 .memory_type = MEMTYPE_EBI1,
1733};
1734
1735static struct platform_device android_pmem_adsp_device = {
1736 .name = "android_pmem",
1737 .id = 1,
1738 .dev = { .platform_data = &android_pmem_adsp_pdata },
1739};
1740
1741static unsigned pmem_mdp_size = MSM_PMEM_MDP_SIZE;
1742static int __init pmem_mdp_size_setup(char *p)
1743{
1744 pmem_mdp_size = memparse(p, NULL);
1745 return 0;
1746}
1747
1748early_param("pmem_mdp_size", pmem_mdp_size_setup);
1749
1750static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
1751static int __init pmem_adsp_size_setup(char *p)
1752{
1753 pmem_adsp_size = memparse(p, NULL);
1754 return 0;
1755}
1756
1757early_param("pmem_adsp_size", pmem_adsp_size_setup);
1758
1759static unsigned fb_size = MSM_FB_SIZE;
1760static int __init fb_size_setup(char *p)
1761{
1762 fb_size = memparse(p, NULL);
1763 return 0;
1764}
1765
1766early_param("fb_size", fb_size_setup);
1767
Justin Paupored98328e2011-08-19 13:48:31 -07001768static struct regulator_bulk_data regs_lcdc[] = {
1769 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
1770 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001771};
1772
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001773static uint32_t lcdc_gpio_initialized;
1774
1775static void lcdc_toshiba_gpio_init(void)
1776{
Justin Paupored98328e2011-08-19 13:48:31 -07001777 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001778 if (!lcdc_gpio_initialized) {
1779 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
1780 pr_err("failed to request gpio spi_clk\n");
1781 return;
1782 }
1783 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
1784 pr_err("failed to request gpio spi_cs0_N\n");
1785 goto fail_gpio6;
1786 }
1787 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
1788 pr_err("failed to request gpio spi_mosi\n");
1789 goto fail_gpio5;
1790 }
1791 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
1792 pr_err("failed to request gpio spi_miso\n");
1793 goto fail_gpio4;
1794 }
1795 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
1796 pr_err("failed to request gpio_disp_pwr\n");
1797 goto fail_gpio3;
1798 }
1799 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
1800 pr_err("failed to request gpio_bkl_en\n");
1801 goto fail_gpio2;
1802 }
1803 pmapp_disp_backlight_init();
1804
Justin Paupored98328e2011-08-19 13:48:31 -07001805 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc), regs_lcdc);
1806 if (rc) {
1807 pr_err("%s: could not get regulators: %d\n",
1808 __func__, rc);
1809 goto fail_gpio1;
1810 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001811
Justin Paupored98328e2011-08-19 13:48:31 -07001812 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
1813 regs_lcdc);
1814 if (rc) {
1815 pr_err("%s: could not set voltages: %d\n",
1816 __func__, rc);
1817 goto fail_vreg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001818 }
1819 lcdc_gpio_initialized = 1;
1820 }
1821 return;
Justin Paupored98328e2011-08-19 13:48:31 -07001822fail_vreg:
1823 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001824fail_gpio1:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001825 gpio_free(GPIO_BACKLIGHT_EN);
1826fail_gpio2:
1827 gpio_free(GPIO_DISPLAY_PWR_EN);
1828fail_gpio3:
1829 gpio_free(GPIO_SPI_MISO);
1830fail_gpio4:
1831 gpio_free(GPIO_SPI_MOSI);
1832fail_gpio5:
1833 gpio_free(GPIO_SPI_CS0_N);
1834fail_gpio6:
1835 gpio_free(GPIO_SPI_CLK);
1836 lcdc_gpio_initialized = 0;
1837}
1838
1839static uint32_t lcdc_gpio_table[] = {
1840 GPIO_SPI_CLK,
1841 GPIO_SPI_CS0_N,
1842 GPIO_SPI_MOSI,
1843 GPIO_DISPLAY_PWR_EN,
1844 GPIO_BACKLIGHT_EN,
1845 GPIO_SPI_MISO,
1846};
1847
1848static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
1849{
1850 int n;
1851
1852 if (lcdc_gpio_initialized) {
1853 /* All are IO Expander GPIOs */
1854 for (n = 0; n < (len - 1); n++)
1855 gpio_direction_output(table[n], 1);
1856 }
1857}
1858
1859static void lcdc_toshiba_config_gpios(int enable)
1860{
1861 config_lcdc_gpio_table(lcdc_gpio_table,
1862 ARRAY_SIZE(lcdc_gpio_table), enable);
1863}
1864
1865static int msm_fb_lcdc_power_save(int on)
1866{
Justin Paupored98328e2011-08-19 13:48:31 -07001867 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001868 /* Doing the init of the LCDC GPIOs very late as they are from
1869 an I2C-controlled IO Expander */
1870 lcdc_toshiba_gpio_init();
1871
1872 if (lcdc_gpio_initialized) {
1873 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1874 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
1875
Justin Paupored98328e2011-08-19 13:48:31 -07001876 rc = on ? regulator_bulk_enable(
1877 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
1878 regulator_bulk_disable(
1879 ARRAY_SIZE(regs_lcdc), regs_lcdc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001880
Justin Paupored98328e2011-08-19 13:48:31 -07001881 if (rc)
1882 pr_err("%s: could not %sable regulators: %d\n",
1883 __func__, on ? "en" : "dis", rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001884 }
1885
1886 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001887}
1888
1889
1890static int lcdc_toshiba_set_bl(int level)
1891{
1892 int ret;
1893
1894 ret = pmapp_disp_backlight_set_brightness(level);
1895 if (ret)
1896 pr_err("%s: can't set lcd backlight!\n", __func__);
1897
1898 return ret;
1899}
1900
1901
1902static struct lcdc_platform_data lcdc_pdata = {
Jeevan Shriram15f2a5e2011-07-13 21:45:26 +05301903 .lcdc_gpio_config = NULL,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001904 .lcdc_power_save = msm_fb_lcdc_power_save,
1905};
1906
1907static int lcd_panel_spi_gpio_num[] = {
1908 GPIO_SPI_MOSI, /* spi_sdi */
1909 GPIO_SPI_MISO, /* spi_sdoi */
1910 GPIO_SPI_CLK, /* spi_clk */
1911 GPIO_SPI_CS0_N, /* spi_cs */
1912};
1913
1914static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
1915 .panel_config_gpio = lcdc_toshiba_config_gpios,
1916 .pmic_backlight = lcdc_toshiba_set_bl,
1917 .gpio_num = lcd_panel_spi_gpio_num,
1918};
1919
1920static struct platform_device lcdc_toshiba_panel_device = {
1921 .name = "lcdc_toshiba_fwvga_pt",
1922 .id = 0,
1923 .dev = {
1924 .platform_data = &lcdc_toshiba_panel_data,
1925 }
1926};
1927
1928static struct resource msm_fb_resources[] = {
1929 {
1930 .flags = IORESOURCE_DMA,
1931 }
1932};
1933
Ajay Singh Parmareede70e2011-08-24 17:36:08 +05301934#define PANEL_NAME_MAX_LEN 30
1935#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
1936#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
1937
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001938static int msm_fb_detect_panel(const char *name)
1939{
Taniya Das0a5303a2011-08-23 18:47:48 +05301940 int ret = -ENODEV;
1941
1942 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
1943 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
1944 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
1945 ret = 0;
Jeevan Shriram29c9e952011-10-27 11:22:46 +05301946 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()) {
Taniya Das0a5303a2011-08-23 18:47:48 +05301947 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
1948 ret = 0;
1949 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001950
Ajay Singh Parmareede70e2011-08-24 17:36:08 +05301951#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
1952 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
1953 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
1954 if (machine_is_msm7x27a_surf() ||
1955 machine_is_msm7625a_surf()) {
1956 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
1957 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
1958 PANEL_NAME_MAX_LEN)))
1959 return 0;
1960 }
1961#endif
Taniya Das0a5303a2011-08-23 18:47:48 +05301962 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001963}
1964
1965static struct msm_fb_platform_data msm_fb_pdata = {
1966 .detect_client = msm_fb_detect_panel,
1967};
1968
1969static struct platform_device msm_fb_device = {
1970 .name = "msm_fb",
1971 .id = 0,
1972 .num_resources = ARRAY_SIZE(msm_fb_resources),
1973 .resource = msm_fb_resources,
1974 .dev = {
1975 .platform_data = &msm_fb_pdata,
1976 }
1977};
1978
1979#ifdef CONFIG_FB_MSM_MIPI_DSI
1980static int mipi_renesas_set_bl(int level)
1981{
1982 int ret;
1983
1984 ret = pmapp_disp_backlight_set_brightness(level);
1985
1986 if (ret)
1987 pr_err("%s: can't set lcd backlight!\n", __func__);
1988
1989 return ret;
1990}
1991
1992static struct msm_panel_common_pdata mipi_renesas_pdata = {
1993 .pmic_backlight = mipi_renesas_set_bl,
1994};
1995
1996
1997static struct platform_device mipi_dsi_renesas_panel_device = {
1998 .name = "mipi_renesas",
1999 .id = 0,
2000 .dev = {
2001 .platform_data = &mipi_renesas_pdata,
2002 }
2003};
2004#endif
2005
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002006#define SND(desc, num) { .name = #desc, .id = num }
2007static struct snd_endpoint snd_endpoints_list[] = {
2008 SND(HANDSET, 0),
2009 SND(MONO_HEADSET, 2),
2010 SND(HEADSET, 3),
2011 SND(SPEAKER, 6),
2012 SND(TTY_HEADSET, 8),
2013 SND(TTY_VCO, 9),
2014 SND(TTY_HCO, 10),
2015 SND(BT, 12),
2016 SND(IN_S_SADC_OUT_HANDSET, 16),
2017 SND(IN_S_SADC_OUT_SPEAKER_PHONE, 25),
2018 SND(FM_DIGITAL_STEREO_HEADSET, 26),
2019 SND(FM_DIGITAL_SPEAKER_PHONE, 27),
2020 SND(FM_DIGITAL_BT_A2DP_HEADSET, 28),
Shashi Kumar64e07602011-10-11 13:18:57 +05302021 SND(STEREO_HEADSET_AND_SPEAKER, 31),
Sidipotu Ashokab34ca42011-07-22 16:34:20 +05302022 SND(CURRENT, 0x7FFFFFFE),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002023 SND(FM_ANALOG_STEREO_HEADSET, 35),
2024 SND(FM_ANALOG_STEREO_HEADSET_CODEC, 36),
2025};
2026#undef SND
2027
2028static struct msm_snd_endpoints msm_device_snd_endpoints = {
2029 .endpoints = snd_endpoints_list,
2030 .num = sizeof(snd_endpoints_list) / sizeof(struct snd_endpoint)
2031};
2032
2033static struct platform_device msm_device_snd = {
2034 .name = "msm_snd",
2035 .id = -1,
2036 .dev = {
2037 .platform_data = &msm_device_snd_endpoints
2038 },
2039};
2040
2041#define DEC0_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
2042 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
2043 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
2044 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
2045 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
2046 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
2047#define DEC1_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
2048 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
2049 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
2050 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
2051 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
2052 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
2053#define DEC2_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
2054 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
2055 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
2056 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
2057 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
2058 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
2059#define DEC3_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
2060 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
2061 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
2062 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
2063 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
2064 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
2065#define DEC4_FORMAT (1<<MSM_ADSP_CODEC_MIDI)
2066
2067static unsigned int dec_concurrency_table[] = {
2068 /* Audio LP */
2069 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DMA)), 0,
2070 0, 0, 0,
2071
2072 /* Concurrency 1 */
2073 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2074 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2075 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2076 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2077 (DEC4_FORMAT),
2078
2079 /* Concurrency 2 */
2080 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2081 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2082 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2083 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2084 (DEC4_FORMAT),
2085
2086 /* Concurrency 3 */
2087 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2088 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2089 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2090 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2091 (DEC4_FORMAT),
2092
2093 /* Concurrency 4 */
2094 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2095 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2096 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2097 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2098 (DEC4_FORMAT),
2099
2100 /* Concurrency 5 */
2101 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
2102 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2103 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2104 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2105 (DEC4_FORMAT),
2106
2107 /* Concurrency 6 */
2108 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2109 0, 0, 0, 0,
2110
2111 /* Concurrency 7 */
2112 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2113 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2114 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2115 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
2116 (DEC4_FORMAT),
2117};
2118
2119#define DEC_INFO(name, queueid, decid, nr_codec) { .module_name = name, \
2120 .module_queueid = queueid, .module_decid = decid, \
2121 .nr_codec_support = nr_codec}
2122
2123static struct msm_adspdec_info dec_info_list[] = {
2124 DEC_INFO("AUDPLAY0TASK", 13, 0, 11), /* AudPlay0BitStreamCtrlQueue */
2125 DEC_INFO("AUDPLAY1TASK", 14, 1, 11), /* AudPlay1BitStreamCtrlQueue */
2126 DEC_INFO("AUDPLAY2TASK", 15, 2, 11), /* AudPlay2BitStreamCtrlQueue */
2127 DEC_INFO("AUDPLAY3TASK", 16, 3, 11), /* AudPlay3BitStreamCtrlQueue */
2128 DEC_INFO("AUDPLAY4TASK", 17, 4, 1), /* AudPlay4BitStreamCtrlQueue */
2129};
2130
2131static struct msm_adspdec_database msm_device_adspdec_database = {
2132 .num_dec = ARRAY_SIZE(dec_info_list),
2133 .num_concurrency_support = (ARRAY_SIZE(dec_concurrency_table) / \
2134 ARRAY_SIZE(dec_info_list)),
2135 .dec_concurrency_table = dec_concurrency_table,
2136 .dec_info_list = dec_info_list,
2137};
2138
2139static struct platform_device msm_device_adspdec = {
2140 .name = "msm_adspdec",
2141 .id = -1,
2142 .dev = {
2143 .platform_data = &msm_device_adspdec_database
2144 },
2145};
2146
2147static struct android_pmem_platform_data android_pmem_audio_pdata = {
2148 .name = "pmem_audio",
2149 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2150 .cached = 0,
2151 .memory_type = MEMTYPE_EBI1,
2152};
2153
2154static struct platform_device android_pmem_audio_device = {
2155 .name = "android_pmem",
2156 .id = 2,
2157 .dev = { .platform_data = &android_pmem_audio_pdata },
2158};
2159
2160static struct android_pmem_platform_data android_pmem_pdata = {
2161 .name = "pmem",
2162 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2163 .cached = 1,
2164 .memory_type = MEMTYPE_EBI1,
2165};
2166static struct platform_device android_pmem_device = {
2167 .name = "android_pmem",
2168 .id = 0,
2169 .dev = { .platform_data = &android_pmem_pdata },
2170};
2171
2172static u32 msm_calculate_batt_capacity(u32 current_voltage);
2173
2174static struct msm_psy_batt_pdata msm_psy_batt_data = {
2175 .voltage_min_design = 2800,
2176 .voltage_max_design = 4300,
2177 .avail_chg_sources = AC_CHG | USB_CHG ,
2178 .batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
2179 .calculate_capacity = &msm_calculate_batt_capacity,
2180};
2181
2182static u32 msm_calculate_batt_capacity(u32 current_voltage)
2183{
2184 u32 low_voltage = msm_psy_batt_data.voltage_min_design;
2185 u32 high_voltage = msm_psy_batt_data.voltage_max_design;
2186
2187 return (current_voltage - low_voltage) * 100
2188 / (high_voltage - low_voltage);
2189}
2190
2191static struct platform_device msm_batt_device = {
2192 .name = "msm-battery",
2193 .id = -1,
2194 .dev.platform_data = &msm_psy_batt_data,
2195};
2196
2197static struct smsc911x_platform_config smsc911x_config = {
2198 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
2199 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
2200 .flags = SMSC911X_USE_16BIT,
2201};
2202
2203static struct resource smsc911x_resources[] = {
2204 [0] = {
2205 .start = 0x90000000,
2206 .end = 0x90007fff,
2207 .flags = IORESOURCE_MEM,
2208 },
2209 [1] = {
2210 .start = MSM_GPIO_TO_INT(48),
2211 .end = MSM_GPIO_TO_INT(48),
2212 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
2213 },
2214};
2215
2216static struct platform_device smsc911x_device = {
2217 .name = "smsc911x",
2218 .id = 0,
2219 .num_resources = ARRAY_SIZE(smsc911x_resources),
2220 .resource = smsc911x_resources,
2221 .dev = {
2222 .platform_data = &smsc911x_config,
2223 },
2224};
2225
2226static struct msm_gpio smsc911x_gpios[] = {
2227 { GPIO_CFG(48, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
2228 "smsc911x_irq" },
2229 { GPIO_CFG(49, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
2230 "eth_fifo_sel" },
2231};
2232
2233#define ETH_FIFO_SEL_GPIO 49
2234static void msm7x27a_cfg_smsc911x(void)
2235{
2236 int res;
2237
2238 res = msm_gpios_request_enable(smsc911x_gpios,
2239 ARRAY_SIZE(smsc911x_gpios));
2240 if (res) {
2241 pr_err("%s: unable to enable gpios for SMSC911x\n", __func__);
2242 return;
2243 }
2244
2245 /* ETH_FIFO_SEL */
2246 res = gpio_direction_output(ETH_FIFO_SEL_GPIO, 0);
2247 if (res) {
2248 pr_err("%s: unable to get direction for gpio %d\n", __func__,
2249 ETH_FIFO_SEL_GPIO);
2250 msm_gpios_disable_free(smsc911x_gpios,
2251 ARRAY_SIZE(smsc911x_gpios));
2252 return;
2253 }
2254 gpio_set_value(ETH_FIFO_SEL_GPIO, 0);
2255}
2256
2257#ifdef CONFIG_MSM_CAMERA
2258static uint32_t camera_off_gpio_table[] = {
2259 GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
2260};
2261
2262static uint32_t camera_on_gpio_table[] = {
2263 GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
2264};
2265
2266#ifdef CONFIG_MSM_CAMERA_FLASH
2267static struct msm_camera_sensor_flash_src msm_flash_src = {
Nishant Pandit474f2252011-07-23 23:17:56 +05302268 .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
2269 ._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
2270 ._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002271};
2272#endif
2273
Justin Paupored98328e2011-08-19 13:48:31 -07002274static struct regulator_bulk_data regs_camera[] = {
2275 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
2276 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
2277 { .supply = "usb2", .min_uV = 1800000, .max_uV = 1800000 },
2278};
2279
2280static void __init msm_camera_vreg_init(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002281{
2282 int rc;
2283
Justin Paupored98328e2011-08-19 13:48:31 -07002284 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002285
Justin Paupored98328e2011-08-19 13:48:31 -07002286 if (rc) {
2287 pr_err("%s: could not get regulators: %d\n", __func__, rc);
2288 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002289 }
2290
Justin Paupored98328e2011-08-19 13:48:31 -07002291 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002292
Justin Paupored98328e2011-08-19 13:48:31 -07002293 if (rc) {
2294 pr_err("%s: could not set voltages: %d\n", __func__, rc);
2295 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002296 }
Justin Paupored98328e2011-08-19 13:48:31 -07002297}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002298
Justin Paupored98328e2011-08-19 13:48:31 -07002299static void msm_camera_vreg_config(int vreg_en)
2300{
2301 int rc = vreg_en ?
2302 regulator_bulk_enable(ARRAY_SIZE(regs_camera), regs_camera) :
2303 regulator_bulk_disable(ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002304
Justin Paupored98328e2011-08-19 13:48:31 -07002305 if (rc)
2306 pr_err("%s: could not %sable regulators: %d\n",
2307 __func__, vreg_en ? "en" : "dis", rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002308}
2309
2310static int config_gpio_table(uint32_t *table, int len)
2311{
2312 int rc = 0, i = 0;
2313
2314 for (i = 0; i < len; i++) {
2315 rc = gpio_tlmm_config(table[i], GPIO_CFG_ENABLE);
2316 if (rc) {
2317 pr_err("%s not able to get gpio\n", __func__);
2318 for (i--; i >= 0; i--)
2319 gpio_tlmm_config(camera_off_gpio_table[i],
2320 GPIO_CFG_ENABLE);
2321 break;
2322 }
2323 }
2324 return rc;
2325}
2326
2327static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data;
2328static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data;
2329static int config_camera_on_gpios_rear(void)
2330{
2331 int rc = 0;
2332
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302333 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002334 msm_camera_vreg_config(1);
2335
2336 rc = config_gpio_table(camera_on_gpio_table,
2337 ARRAY_SIZE(camera_on_gpio_table));
2338 if (rc < 0) {
2339 pr_err("%s: CAMSENSOR gpio table request"
2340 "failed\n", __func__);
2341 return rc;
2342 }
2343
2344 return rc;
2345}
2346
2347static void config_camera_off_gpios_rear(void)
2348{
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302349 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002350 msm_camera_vreg_config(0);
2351
2352 config_gpio_table(camera_off_gpio_table,
2353 ARRAY_SIZE(camera_off_gpio_table));
2354}
2355
2356static int config_camera_on_gpios_front(void)
2357{
2358 int rc = 0;
2359
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302360 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002361 msm_camera_vreg_config(1);
2362
2363 rc = config_gpio_table(camera_on_gpio_table,
2364 ARRAY_SIZE(camera_on_gpio_table));
2365 if (rc < 0) {
2366 pr_err("%s: CAMSENSOR gpio table request"
2367 "failed\n", __func__);
2368 return rc;
2369 }
2370
2371 return rc;
2372}
2373
2374static void config_camera_off_gpios_front(void)
2375{
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302376 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002377 msm_camera_vreg_config(0);
2378
2379 config_gpio_table(camera_off_gpio_table,
2380 ARRAY_SIZE(camera_off_gpio_table));
2381}
2382
2383struct msm_camera_device_platform_data msm_camera_device_data_rear = {
2384 .camera_gpio_on = config_camera_on_gpios_rear,
2385 .camera_gpio_off = config_camera_off_gpios_rear,
2386 .ioext.csiphy = 0xA1000000,
2387 .ioext.csisz = 0x00100000,
2388 .ioext.csiirq = INT_CSI_IRQ_1,
2389 .ioclk.mclk_clk_rate = 24000000,
2390 .ioclk.vfe_clk_rate = 192000000,
2391 .ioext.appphy = MSM_CLK_CTL_PHYS,
2392 .ioext.appsz = MSM_CLK_CTL_SIZE,
2393};
2394
2395struct msm_camera_device_platform_data msm_camera_device_data_front = {
2396 .camera_gpio_on = config_camera_on_gpios_front,
2397 .camera_gpio_off = config_camera_off_gpios_front,
2398 .ioext.csiphy = 0xA0F00000,
2399 .ioext.csisz = 0x00100000,
2400 .ioext.csiirq = INT_CSI_IRQ_0,
2401 .ioclk.mclk_clk_rate = 24000000,
2402 .ioclk.vfe_clk_rate = 192000000,
2403 .ioext.appphy = MSM_CLK_CTL_PHYS,
2404 .ioext.appsz = MSM_CLK_CTL_SIZE,
2405};
2406
2407#ifdef CONFIG_S5K4E1
2408static struct msm_camera_sensor_platform_info s5k4e1_sensor_7627a_info = {
2409 .mount_angle = 90
2410};
2411
2412static struct msm_camera_sensor_flash_data flash_s5k4e1 = {
2413 .flash_type = MSM_CAMERA_FLASH_LED,
2414 .flash_src = &msm_flash_src
2415};
2416
2417static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
2418 .sensor_name = "s5k4e1",
2419 .sensor_reset_enable = 1,
2420 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N,
2421 .sensor_pwd = 85,
2422 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
2423 .vcm_enable = 1,
2424 .pdata = &msm_camera_device_data_rear,
2425 .flash_data = &flash_s5k4e1,
2426 .sensor_platform_info = &s5k4e1_sensor_7627a_info,
2427 .csi_if = 1
2428};
2429
2430static struct platform_device msm_camera_sensor_s5k4e1 = {
2431 .name = "msm_camera_s5k4e1",
2432 .dev = {
2433 .platform_data = &msm_camera_sensor_s5k4e1_data,
2434 },
2435};
2436#endif
2437
2438#ifdef CONFIG_IMX072
2439static struct msm_camera_sensor_platform_info imx072_sensor_7627a_info = {
2440 .mount_angle = 90
2441};
2442
2443static struct msm_camera_sensor_flash_data flash_imx072 = {
2444 .flash_type = MSM_CAMERA_FLASH_LED,
2445 .flash_src = &msm_flash_src
2446};
2447
2448static struct msm_camera_sensor_info msm_camera_sensor_imx072_data = {
2449 .sensor_name = "imx072",
2450 .sensor_reset_enable = 1,
2451 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N, /* TODO 106,*/
2452 .sensor_pwd = 85,
2453 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
2454 .vcm_enable = 1,
2455 .pdata = &msm_camera_device_data_rear,
2456 .flash_data = &flash_imx072,
2457 .sensor_platform_info = &imx072_sensor_7627a_info,
2458 .csi_if = 1
2459};
2460
2461static struct platform_device msm_camera_sensor_imx072 = {
2462 .name = "msm_camera_imx072",
2463 .dev = {
2464 .platform_data = &msm_camera_sensor_imx072_data,
2465 },
2466};
2467#endif
2468
2469#ifdef CONFIG_WEBCAM_OV9726
2470static struct msm_camera_sensor_platform_info ov9726_sensor_7627a_info = {
2471 .mount_angle = 90
2472};
2473
2474static struct msm_camera_sensor_flash_data flash_ov9726 = {
2475 .flash_type = MSM_CAMERA_FLASH_NONE,
2476 .flash_src = &msm_flash_src
2477};
2478
2479static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
2480 .sensor_name = "ov9726",
2481 .sensor_reset_enable = 0,
2482 .sensor_reset = GPIO_CAM_GP_CAM1MP_XCLR,
2483 .sensor_pwd = 85,
2484 .vcm_pwd = 1,
2485 .vcm_enable = 0,
2486 .pdata = &msm_camera_device_data_front,
2487 .flash_data = &flash_ov9726,
2488 .sensor_platform_info = &ov9726_sensor_7627a_info,
2489 .csi_if = 1
2490};
2491
2492static struct platform_device msm_camera_sensor_ov9726 = {
2493 .name = "msm_camera_ov9726",
2494 .dev = {
2495 .platform_data = &msm_camera_sensor_ov9726_data,
2496 },
2497};
Justin Paupored98328e2011-08-19 13:48:31 -07002498#else
2499static inline void msm_camera_vreg_init(void) { }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002500#endif
2501
2502#ifdef CONFIG_MT9E013
2503static struct msm_camera_sensor_platform_info mt9e013_sensor_7627a_info = {
2504 .mount_angle = 90
2505};
2506
2507static struct msm_camera_sensor_flash_data flash_mt9e013 = {
2508 .flash_type = MSM_CAMERA_FLASH_LED,
2509 .flash_src = &msm_flash_src
2510};
2511
2512static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
2513 .sensor_name = "mt9e013",
2514 .sensor_reset = 0,
2515 .sensor_reset_enable = 1,
2516 .sensor_pwd = 85,
2517 .vcm_pwd = 1,
2518 .vcm_enable = 0,
2519 .pdata = &msm_camera_device_data_rear,
2520 .flash_data = &flash_mt9e013,
2521 .sensor_platform_info = &mt9e013_sensor_7627a_info,
2522 .csi_if = 1
2523};
2524
2525static struct platform_device msm_camera_sensor_mt9e013 = {
2526 .name = "msm_camera_mt9e013",
2527 .dev = {
2528 .platform_data = &msm_camera_sensor_mt9e013_data,
2529 },
2530};
2531#endif
2532
2533static struct i2c_board_info i2c_camera_devices[] = {
2534 #ifdef CONFIG_S5K4E1
2535 {
2536 I2C_BOARD_INFO("s5k4e1", 0x36),
2537 },
2538 {
2539 I2C_BOARD_INFO("s5k4e1_af", 0x8c >> 1),
2540 },
2541 #endif
2542 #ifdef CONFIG_WEBCAM_OV9726
2543 {
2544 I2C_BOARD_INFO("ov9726", 0x10),
2545 },
2546 #endif
2547 #ifdef CONFIG_IMX072
2548 {
2549 I2C_BOARD_INFO("imx072", 0x34),
2550 },
2551 #endif
2552 #ifdef CONFIG_MT9E013
2553 {
2554 I2C_BOARD_INFO("mt9e013", 0x6C >> 2),
2555 },
2556 #endif
2557 {
Nishant Pandit474f2252011-07-23 23:17:56 +05302558 I2C_BOARD_INFO("sc628a", 0x6E),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002559 },
2560};
2561#endif
2562#if defined(CONFIG_SERIAL_MSM_HSL_CONSOLE) \
2563 && defined(CONFIG_MSM_SHARED_GPIO_FOR_UART2DM)
2564static struct msm_gpio uart2dm_gpios[] = {
2565 {GPIO_CFG(19, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2566 "uart2dm_rfr_n" },
2567 {GPIO_CFG(20, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2568 "uart2dm_cts_n" },
2569 {GPIO_CFG(21, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2570 "uart2dm_rx" },
2571 {GPIO_CFG(108, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2572 "uart2dm_tx" },
2573};
2574
2575static void msm7x27a_cfg_uart2dm_serial(void)
2576{
2577 int ret;
2578 ret = msm_gpios_request_enable(uart2dm_gpios,
2579 ARRAY_SIZE(uart2dm_gpios));
2580 if (ret)
2581 pr_err("%s: unable to enable gpios for uart2dm\n", __func__);
2582}
2583#else
2584static void msm7x27a_cfg_uart2dm_serial(void) { }
2585#endif
2586
2587static struct platform_device *rumi_sim_devices[] __initdata = {
2588 &msm_device_dmov,
2589 &msm_device_smd,
2590 &smc91x_device,
2591 &msm_device_uart1,
2592 &msm_device_nand,
2593 &msm_device_uart_dm1,
2594 &msm_gsbi0_qup_i2c_device,
2595 &msm_gsbi1_qup_i2c_device,
2596};
2597
2598static struct platform_device *surf_ffa_devices[] __initdata = {
2599 &msm_device_dmov,
2600 &msm_device_smd,
2601 &msm_device_uart1,
2602 &msm_device_uart_dm1,
2603 &msm_device_uart_dm2,
2604 &msm_device_nand,
2605 &msm_gsbi0_qup_i2c_device,
2606 &msm_gsbi1_qup_i2c_device,
2607 &msm_device_otg,
2608 &msm_device_gadget_peripheral,
2609 &android_usb_device,
2610 &android_pmem_device,
2611 &android_pmem_adsp_device,
2612 &android_pmem_audio_device,
2613 &msm_device_snd,
2614 &msm_device_adspdec,
2615 &msm_fb_device,
2616 &lcdc_toshiba_panel_device,
2617 &msm_batt_device,
2618 &smsc911x_device,
2619#ifdef CONFIG_S5K4E1
2620 &msm_camera_sensor_s5k4e1,
2621#endif
2622#ifdef CONFIG_IMX072
2623 &msm_camera_sensor_imx072,
2624#endif
2625#ifdef CONFIG_WEBCAM_OV9726
2626 &msm_camera_sensor_ov9726,
2627#endif
2628#ifdef CONFIG_MT9E013
2629 &msm_camera_sensor_mt9e013,
2630#endif
2631#ifdef CONFIG_FB_MSM_MIPI_DSI
2632 &mipi_dsi_renesas_panel_device,
2633#endif
2634 &msm_kgsl_3d0,
2635#ifdef CONFIG_BT
2636 &msm_bt_power_device,
2637#endif
Manish Dewangan3a260992011-06-24 18:01:34 +05302638 &asoc_msm_pcm,
2639 &asoc_msm_dai0,
2640 &asoc_msm_dai1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002641};
2642
2643static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
2644static int __init pmem_kernel_ebi1_size_setup(char *p)
2645{
2646 pmem_kernel_ebi1_size = memparse(p, NULL);
2647 return 0;
2648}
2649early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
2650
2651static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
2652static int __init pmem_audio_size_setup(char *p)
2653{
2654 pmem_audio_size = memparse(p, NULL);
2655 return 0;
2656}
2657early_param("pmem_audio_size", pmem_audio_size_setup);
2658
2659static void __init msm_msm7x2x_allocate_memory_regions(void)
2660{
2661 void *addr;
2662 unsigned long size;
2663
Jeevan Shriramf40764e2011-10-31 23:28:26 +05302664 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
2665 fb_size = MSM7x25A_MSM_FB_SIZE;
2666 else
2667 fb_size = MSM_FB_SIZE;
2668
2669 size = fb_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002670 addr = alloc_bootmem_align(size, 0x1000);
2671 msm_fb_resources[0].start = __pa(addr);
2672 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
2673 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
2674 size, addr, __pa(addr));
2675}
2676
2677static struct memtype_reserve msm7x27a_reserve_table[] __initdata = {
2678 [MEMTYPE_SMI] = {
2679 },
2680 [MEMTYPE_EBI0] = {
2681 .flags = MEMTYPE_FLAGS_1M_ALIGN,
2682 },
2683 [MEMTYPE_EBI1] = {
2684 .flags = MEMTYPE_FLAGS_1M_ALIGN,
2685 },
2686};
2687
2688static void __init size_pmem_devices(void)
2689{
Jeevan Shriramf40764e2011-10-31 23:28:26 +05302690
2691 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
2692 pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
2693 pmem_adsp_size = MSM7x25A_MSM_PMEM_ADSP_SIZE;
2694 } else {
2695 pmem_mdp_size = MSM_PMEM_MDP_SIZE;
2696 pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
2697 }
2698
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002699#ifdef CONFIG_ANDROID_PMEM
2700 android_pmem_adsp_pdata.size = pmem_adsp_size;
2701 android_pmem_pdata.size = pmem_mdp_size;
2702 android_pmem_audio_pdata.size = pmem_audio_size;
2703#endif
2704}
2705
2706static void __init reserve_memory_for(struct android_pmem_platform_data *p)
2707{
2708 msm7x27a_reserve_table[p->memory_type].size += p->size;
2709}
2710
2711static void __init reserve_pmem_memory(void)
2712{
2713#ifdef CONFIG_ANDROID_PMEM
2714 reserve_memory_for(&android_pmem_adsp_pdata);
2715 reserve_memory_for(&android_pmem_pdata);
2716 reserve_memory_for(&android_pmem_audio_pdata);
2717 msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
2718#endif
2719}
2720
2721static void __init msm7x27a_calculate_reserve_sizes(void)
2722{
2723 size_pmem_devices();
2724 reserve_pmem_memory();
2725}
2726
2727static int msm7x27a_paddr_to_memtype(unsigned int paddr)
2728{
2729 return MEMTYPE_EBI1;
2730}
2731
2732static struct reserve_info msm7x27a_reserve_info __initdata = {
2733 .memtype_reserve_table = msm7x27a_reserve_table,
2734 .calculate_reserve_sizes = msm7x27a_calculate_reserve_sizes,
2735 .paddr_to_memtype = msm7x27a_paddr_to_memtype,
2736};
2737
2738static void __init msm7x27a_reserve(void)
2739{
2740 reserve_info = &msm7x27a_reserve_info;
2741 msm_reserve();
2742}
2743
2744static void __init msm_device_i2c_init(void)
2745{
2746 msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
2747 msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
2748}
2749
2750static struct msm_panel_common_pdata mdp_pdata = {
2751 .gpio = 97,
2752 .mdp_rev = MDP_REV_303,
2753};
2754
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302755
2756#ifdef CONFIG_FB_MSM
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002757#define GPIO_LCDC_BRDG_PD 128
2758#define GPIO_LCDC_BRDG_RESET_N 129
2759
2760#define LCDC_RESET_PHYS 0x90008014
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302761
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002762static void __iomem *lcdc_reset_ptr;
2763
2764static unsigned mipi_dsi_gpio[] = {
2765 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2766 GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
2767 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2768 GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
2769};
2770
2771enum {
2772 DSI_SINGLE_LANE = 1,
2773 DSI_TWO_LANES,
2774};
2775
2776static int msm_fb_get_lane_config(void)
2777{
2778 int rc = DSI_TWO_LANES;
2779
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302780 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002781 rc = DSI_SINGLE_LANE;
2782 pr_info("DSI Single Lane\n");
2783 } else {
2784 pr_info("DSI Two Lanes\n");
2785 }
2786 return rc;
2787}
2788
2789static int msm_fb_dsi_client_reset(void)
2790{
2791 int rc = 0;
2792
2793 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
2794 if (rc < 0) {
2795 pr_err("failed to request lcd brdg reset_n\n");
2796 return rc;
2797 }
2798
2799 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
2800 if (rc < 0) {
2801 pr_err("failed to request lcd brdg pd\n");
2802 return rc;
2803 }
2804
2805 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
2806 if (rc) {
2807 pr_err("Failed to enable LCDC Bridge reset enable\n");
2808 goto gpio_error;
2809 }
2810
2811 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
2812 if (rc) {
2813 pr_err("Failed to enable LCDC Bridge pd enable\n");
2814 goto gpio_error2;
2815 }
2816
2817 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
2818 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
2819 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
2820
2821 if (!rc) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302822 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002823 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
2824 sizeof(uint32_t));
2825
2826 if (!lcdc_reset_ptr)
2827 return 0;
2828 }
2829 return rc;
2830 } else {
2831 goto gpio_error;
2832 }
2833
2834gpio_error2:
2835 pr_err("Failed GPIO bridge pd\n");
2836 gpio_free(GPIO_LCDC_BRDG_PD);
2837
2838gpio_error:
2839 pr_err("Failed GPIO bridge reset\n");
2840 gpio_free(GPIO_LCDC_BRDG_RESET_N);
2841 return rc;
2842}
2843
Justin Paupored98328e2011-08-19 13:48:31 -07002844static struct regulator_bulk_data regs_dsi[] = {
2845 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
2846 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002847};
2848
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002849static int dsi_gpio_initialized;
2850
2851static int mipi_dsi_panel_power(int on)
2852{
Justin Paupored98328e2011-08-19 13:48:31 -07002853 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002854 uint32_t lcdc_reset_cfg;
2855
2856 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
Justin Paupored98328e2011-08-19 13:48:31 -07002857 if (unlikely(!dsi_gpio_initialized)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002858 pmapp_disp_backlight_init();
2859
2860 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
2861 if (rc < 0) {
2862 pr_err("failed to request gpio_disp_pwr\n");
2863 return rc;
2864 }
2865
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302866 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002867 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
2868 if (rc < 0) {
2869 pr_err("failed to enable display pwr\n");
2870 goto fail_gpio1;
2871 }
2872
2873 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
2874 if (rc < 0) {
2875 pr_err("failed to request gpio_bkl_en\n");
2876 goto fail_gpio1;
2877 }
2878
2879 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
2880 if (rc < 0) {
2881 pr_err("failed to enable backlight\n");
2882 goto fail_gpio2;
2883 }
2884 }
2885
Justin Paupored98328e2011-08-19 13:48:31 -07002886 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
2887 if (rc) {
2888 pr_err("%s: could not get regulators: %d\n",
2889 __func__, rc);
2890 goto fail_gpio2;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002891 }
Justin Paupored98328e2011-08-19 13:48:31 -07002892
2893 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi), regs_dsi);
2894 if (rc) {
2895 pr_err("%s: could not set voltages: %d\n",
2896 __func__, rc);
2897 goto fail_vreg;
2898 }
2899
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002900 dsi_gpio_initialized = 1;
2901 }
2902
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302903 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Justin Paupored98328e2011-08-19 13:48:31 -07002904 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
2905 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302906 } else if (machine_is_msm7x27a_ffa() ||
2907 machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002908 if (on) {
Justin Paupored98328e2011-08-19 13:48:31 -07002909 /* This line drives an active low pin on FFA */
2910 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
2911 if (rc < 0)
2912 pr_err("failed to set direction for "
2913 "display pwr\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002914 } else {
Justin Paupored98328e2011-08-19 13:48:31 -07002915 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
2916 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
2917 if (rc < 0)
2918 pr_err("failed to set direction for "
2919 "display pwr\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002920 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002921 }
2922
Justin Paupored98328e2011-08-19 13:48:31 -07002923 if (on) {
2924 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
2925
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302926 if (machine_is_msm7x27a_surf() ||
2927 machine_is_msm7625a_surf()) {
Justin Paupored98328e2011-08-19 13:48:31 -07002928 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
2929 rmb();
2930 lcdc_reset_cfg &= ~1;
2931
2932 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
2933 msleep(20);
2934 wmb();
2935 lcdc_reset_cfg |= 1;
2936 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
2937 } else {
2938 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
2939 msleep(20);
2940 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
2941 }
2942
2943 if (pmapp_disp_backlight_set_brightness(100))
2944 pr_err("backlight set brightness failed\n");
2945 } else {
2946 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
2947
2948 if (pmapp_disp_backlight_set_brightness(0))
2949 pr_err("backlight set brightness failed\n");
2950 }
2951
2952 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
2953 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
2954
2955 if (rc)
2956 pr_err("%s: could not %sable regulators: %d\n",
2957 __func__, on ? "en" : "dis", rc);
2958
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002959 return rc;
2960
Justin Paupored98328e2011-08-19 13:48:31 -07002961fail_vreg:
2962 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002963fail_gpio2:
2964 gpio_free(GPIO_BACKLIGHT_EN);
2965fail_gpio1:
2966 gpio_free(GPIO_DISPLAY_PWR_EN);
2967 dsi_gpio_initialized = 0;
2968 return rc;
2969}
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302970#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002971
2972#define MDP_303_VSYNC_GPIO 97
2973
2974#ifdef CONFIG_FB_MSM_MDP303
2975static struct mipi_dsi_platform_data mipi_dsi_pdata = {
2976 .vsync_gpio = MDP_303_VSYNC_GPIO,
2977 .dsi_power_save = mipi_dsi_panel_power,
2978 .dsi_client_reset = msm_fb_dsi_client_reset,
2979 .get_lane_config = msm_fb_get_lane_config,
2980};
2981#endif
2982
2983static void __init msm_fb_add_devices(void)
2984{
2985 msm_fb_register_device("mdp", &mdp_pdata);
2986 msm_fb_register_device("lcdc", &lcdc_pdata);
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302987#ifdef CONFIG_FB_MSM_MDP303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002988 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302989#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002990}
2991
2992#define MSM_EBI2_PHYS 0xa0d00000
2993#define MSM_EBI2_XMEM_CS2_CFG1 0xa0d10030
2994
2995static void __init msm7x27a_init_ebi2(void)
2996{
2997 uint32_t ebi2_cfg;
2998 void __iomem *ebi2_cfg_ptr;
2999
3000 ebi2_cfg_ptr = ioremap_nocache(MSM_EBI2_PHYS, sizeof(uint32_t));
3001 if (!ebi2_cfg_ptr)
3002 return;
3003
3004 ebi2_cfg = readl(ebi2_cfg_ptr);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303005 if (machine_is_msm7x27a_rumi3() || machine_is_msm7x27a_surf() ||
3006 machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003007 ebi2_cfg |= (1 << 4); /* CS2 */
3008
3009 writel(ebi2_cfg, ebi2_cfg_ptr);
3010 iounmap(ebi2_cfg_ptr);
3011
3012 /* Enable A/D MUX[bit 31] from EBI2_XMEM_CS2_CFG1 */
3013 ebi2_cfg_ptr = ioremap_nocache(MSM_EBI2_XMEM_CS2_CFG1,
3014 sizeof(uint32_t));
3015 if (!ebi2_cfg_ptr)
3016 return;
3017
3018 ebi2_cfg = readl(ebi2_cfg_ptr);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303019 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003020 ebi2_cfg |= (1 << 31);
3021
3022 writel(ebi2_cfg, ebi2_cfg_ptr);
3023 iounmap(ebi2_cfg_ptr);
3024}
3025
3026#define ATMEL_TS_I2C_NAME "maXTouch"
Justin Paupored98328e2011-08-19 13:48:31 -07003027
3028static struct regulator_bulk_data regs_atmel[] = {
3029 { .supply = "ldo2", .min_uV = 2850000, .max_uV = 2850000 },
3030 { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
3031};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003032
3033#define ATMEL_TS_GPIO_IRQ 82
3034
3035static int atmel_ts_power_on(bool on)
3036{
Justin Paupored98328e2011-08-19 13:48:31 -07003037 int rc = on ?
3038 regulator_bulk_enable(ARRAY_SIZE(regs_atmel), regs_atmel) :
3039 regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003040
Justin Paupored98328e2011-08-19 13:48:31 -07003041 if (rc)
3042 pr_err("%s: could not %sable regulators: %d\n",
3043 __func__, on ? "en" : "dis", rc);
3044 else
3045 msleep(50);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003046
Justin Paupored98328e2011-08-19 13:48:31 -07003047 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003048}
3049
3050static int atmel_ts_platform_init(struct i2c_client *client)
3051{
3052 int rc;
Justin Paupored98328e2011-08-19 13:48:31 -07003053 struct device *dev = &client->dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003054
Justin Paupored98328e2011-08-19 13:48:31 -07003055 rc = regulator_bulk_get(dev, ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003056 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07003057 dev_err(dev, "%s: could not get regulators: %d\n",
3058 __func__, rc);
3059 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003060 }
3061
Justin Paupored98328e2011-08-19 13:48:31 -07003062 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003063 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07003064 dev_err(dev, "%s: could not set voltages: %d\n",
3065 __func__, rc);
3066 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003067 }
3068
3069 rc = gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
3070 GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
3071 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
3072 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07003073 dev_err(dev, "%s: gpio_tlmm_config for %d failed\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003074 __func__, ATMEL_TS_GPIO_IRQ);
Justin Paupored98328e2011-08-19 13:48:31 -07003075 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003076 }
3077
3078 /* configure touchscreen interrupt gpio */
3079 rc = gpio_request(ATMEL_TS_GPIO_IRQ, "atmel_maxtouch_gpio");
3080 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07003081 dev_err(dev, "%s: unable to request gpio %d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003082 __func__, ATMEL_TS_GPIO_IRQ);
3083 goto ts_gpio_tlmm_unconfig;
3084 }
3085
3086 rc = gpio_direction_input(ATMEL_TS_GPIO_IRQ);
3087 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -07003088 dev_err(dev, "%s: unable to set the direction of gpio %d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003089 __func__, ATMEL_TS_GPIO_IRQ);
3090 goto free_ts_gpio;
3091 }
3092 return 0;
3093
3094free_ts_gpio:
3095 gpio_free(ATMEL_TS_GPIO_IRQ);
3096ts_gpio_tlmm_unconfig:
3097 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
3098 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
3099 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
Justin Paupored98328e2011-08-19 13:48:31 -07003100reg_free:
3101 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
3102out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003103 return rc;
3104}
3105
3106static int atmel_ts_platform_exit(struct i2c_client *client)
3107{
3108 gpio_free(ATMEL_TS_GPIO_IRQ);
3109 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
3110 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
3111 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
Justin Paupored98328e2011-08-19 13:48:31 -07003112 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003113 return 0;
3114}
3115
3116static u8 atmel_ts_read_chg(void)
3117{
3118 return gpio_get_value(ATMEL_TS_GPIO_IRQ);
3119}
3120
3121static u8 atmel_ts_valid_interrupt(void)
3122{
3123 return !atmel_ts_read_chg();
3124}
3125
3126#define ATMEL_X_OFFSET 13
3127#define ATMEL_Y_OFFSET 0
3128
Mohan Pallaka4e9a94e2011-11-23 16:34:21 +05303129static struct maxtouch_platform_data atmel_ts_pdata = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003130 .numtouch = 4,
3131 .init_platform_hw = atmel_ts_platform_init,
3132 .exit_platform_hw = atmel_ts_platform_exit,
3133 .power_on = atmel_ts_power_on,
3134 .display_res_x = 480,
3135 .display_res_y = 864,
3136 .min_x = ATMEL_X_OFFSET,
3137 .max_x = (505 - ATMEL_X_OFFSET),
3138 .min_y = ATMEL_Y_OFFSET,
3139 .max_y = (863 - ATMEL_Y_OFFSET),
3140 .valid_interrupt = atmel_ts_valid_interrupt,
3141 .read_chg = atmel_ts_read_chg,
3142};
3143
3144static struct i2c_board_info atmel_ts_i2c_info[] __initdata = {
3145 {
3146 I2C_BOARD_INFO(ATMEL_TS_I2C_NAME, 0x4a),
3147 .platform_data = &atmel_ts_pdata,
3148 .irq = MSM_GPIO_TO_INT(ATMEL_TS_GPIO_IRQ),
3149 },
3150};
3151
3152#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))
3153
3154static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
3155static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
3156
3157static const unsigned short keymap[ARRAY_SIZE(kp_col_gpios) *
3158 ARRAY_SIZE(kp_row_gpios)] = {
3159 [KP_INDEX(0, 0)] = KEY_7,
3160 [KP_INDEX(0, 1)] = KEY_DOWN,
3161 [KP_INDEX(0, 2)] = KEY_UP,
3162 [KP_INDEX(0, 3)] = KEY_RIGHT,
3163 [KP_INDEX(0, 4)] = KEY_ENTER,
3164
3165 [KP_INDEX(1, 0)] = KEY_LEFT,
3166 [KP_INDEX(1, 1)] = KEY_SEND,
3167 [KP_INDEX(1, 2)] = KEY_1,
3168 [KP_INDEX(1, 3)] = KEY_4,
3169 [KP_INDEX(1, 4)] = KEY_CLEAR,
3170
3171 [KP_INDEX(2, 0)] = KEY_6,
3172 [KP_INDEX(2, 1)] = KEY_5,
3173 [KP_INDEX(2, 2)] = KEY_8,
3174 [KP_INDEX(2, 3)] = KEY_3,
3175 [KP_INDEX(2, 4)] = KEY_NUMERIC_STAR,
3176
3177 [KP_INDEX(3, 0)] = KEY_9,
3178 [KP_INDEX(3, 1)] = KEY_NUMERIC_POUND,
3179 [KP_INDEX(3, 2)] = KEY_0,
3180 [KP_INDEX(3, 3)] = KEY_2,
3181 [KP_INDEX(3, 4)] = KEY_SLEEP,
3182
3183 [KP_INDEX(4, 0)] = KEY_BACK,
3184 [KP_INDEX(4, 1)] = KEY_HOME,
3185 [KP_INDEX(4, 2)] = KEY_MENU,
3186 [KP_INDEX(4, 3)] = KEY_VOLUMEUP,
3187 [KP_INDEX(4, 4)] = KEY_VOLUMEDOWN,
3188};
3189
3190/* SURF keypad platform device information */
3191static struct gpio_event_matrix_info kp_matrix_info = {
3192 .info.func = gpio_event_matrix_func,
3193 .keymap = keymap,
3194 .output_gpios = kp_row_gpios,
3195 .input_gpios = kp_col_gpios,
3196 .noutputs = ARRAY_SIZE(kp_row_gpios),
3197 .ninputs = ARRAY_SIZE(kp_col_gpios),
3198 .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
3199 .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
3200 .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
3201 GPIOKPF_PRINT_UNMAPPED_KEYS,
3202};
3203
3204static struct gpio_event_info *kp_info[] = {
3205 &kp_matrix_info.info
3206};
3207
3208static struct gpio_event_platform_data kp_pdata = {
3209 .name = "7x27a_kp",
3210 .info = kp_info,
3211 .info_count = ARRAY_SIZE(kp_info)
3212};
3213
3214static struct platform_device kp_pdev = {
3215 .name = GPIO_EVENT_DEV_NAME,
3216 .id = -1,
3217 .dev = {
3218 .platform_data = &kp_pdata,
3219 },
3220};
3221
3222static struct msm_handset_platform_data hs_platform_data = {
3223 .hs_name = "7k_handset",
3224 .pwr_key_delay_ms = 500, /* 0 will disable end key */
3225};
3226
3227static struct platform_device hs_pdev = {
3228 .name = "msm-handset",
3229 .id = -1,
3230 .dev = {
3231 .platform_data = &hs_platform_data,
3232 },
3233};
3234
Justin Pauporeb3a33b72011-08-23 15:30:32 -07003235static struct platform_device msm_proccomm_regulator_dev = {
3236 .name = PROCCOMM_REGULATOR_DEV_NAME,
3237 .id = -1,
3238 .dev = {
3239 .platform_data = &msm7x27a_proccomm_regulator_data
3240 }
3241};
3242
Trilok Soni16f61af2011-07-26 16:06:58 +05303243static void __init msm7627a_rumi3_init(void)
3244{
3245 msm7x27a_init_ebi2();
3246 platform_add_devices(rumi_sim_devices,
3247 ARRAY_SIZE(rumi_sim_devices));
3248}
3249
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003250#define LED_GPIO_PDM 96
3251#define UART1DM_RX_GPIO 45
Santosh Sajjanb479f0f2011-08-18 21:00:44 +05303252
3253#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
3254static int __init msm7x27a_init_ar6000pm(void)
3255{
3256 return platform_device_register(&msm_wlan_ar6000_pm_device);
3257}
3258#else
3259static int __init msm7x27a_init_ar6000pm(void) { return 0; }
3260#endif
3261
Justin Pauporeb3a33b72011-08-23 15:30:32 -07003262static void __init msm7x27a_init_regulators(void)
3263{
3264 int rc = platform_device_register(&msm_proccomm_regulator_dev);
3265 if (rc)
3266 pr_err("%s: could not register regulator device: %d\n",
3267 __func__, rc);
3268}
3269
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003270static void __init msm7x2x_init(void)
3271{
Trilok Sonia416c492011-07-22 20:20:23 +05303272 msm7x2x_misc_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003273
Justin Pauporeb3a33b72011-08-23 15:30:32 -07003274 /* Initialize regulators first so that other devices can use them */
3275 msm7x27a_init_regulators();
3276
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003277 /* Common functions for SURF/FFA/RUMI3 */
3278 msm_device_i2c_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003279 msm7x27a_init_ebi2();
3280 msm7x27a_cfg_uart2dm_serial();
3281#ifdef CONFIG_SERIAL_MSM_HS
3282 msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
3283 msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
3284#endif
3285
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003286#ifdef CONFIG_USB_MSM_OTG_72K
Trilok Soni16f61af2011-07-26 16:06:58 +05303287 msm_otg_pdata.swfi_latency =
3288 msm7x27a_pm_data
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003289 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
Trilok Soni16f61af2011-07-26 16:06:58 +05303290 msm_device_otg.dev.platform_data = &msm_otg_pdata;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003291#endif
Trilok Soni16f61af2011-07-26 16:06:58 +05303292 msm_device_gadget_peripheral.dev.platform_data =
3293 &msm_gadget_pdata;
3294 msm7x27a_cfg_smsc911x();
3295 platform_add_devices(msm_footswitch_devices,
3296 msm_num_footswitch_devices);
3297 platform_add_devices(surf_ffa_devices,
3298 ARRAY_SIZE(surf_ffa_devices));
Sujith Reddy Thummaad7c9a82011-09-30 20:54:38 +05303299 /* Ensure ar6000pm device is registered before MMC/SDC */
3300 msm7x27a_init_ar6000pm();
3301#ifdef CONFIG_MMC_MSM
3302 msm7x27a_init_mmc();
3303#endif
Trilok Soni16f61af2011-07-26 16:06:58 +05303304 msm_fb_add_devices();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003305#ifdef CONFIG_USB_EHCI_MSM_72K
Trilok Soni16f61af2011-07-26 16:06:58 +05303306 msm7x2x_init_host();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003307#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003308
3309 msm_pm_set_platform_data(msm7x27a_pm_data,
3310 ARRAY_SIZE(msm7x27a_pm_data));
Maheshkumar Sivasubramanianc6c55032011-10-25 16:01:32 -06003311 BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003312
3313#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
3314 register_i2c_devices();
3315#endif
3316#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
3317 bt_power_init();
3318#endif
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303319 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003320 atmel_ts_pdata.min_x = 0;
3321 atmel_ts_pdata.max_x = 480;
3322 atmel_ts_pdata.min_y = 0;
3323 atmel_ts_pdata.max_y = 320;
3324 }
3325
3326 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
3327 atmel_ts_i2c_info,
3328 ARRAY_SIZE(atmel_ts_i2c_info));
3329
Pankaj Kumar5be2a3e2011-09-26 11:45:02 +05303330#if defined(CONFIG_MSM_CAMERA)
Justin Paupored98328e2011-08-19 13:48:31 -07003331 msm_camera_vreg_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003332 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
3333 i2c_camera_devices,
3334 ARRAY_SIZE(i2c_camera_devices));
Pankaj Kumar5be2a3e2011-09-26 11:45:02 +05303335#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003336 platform_device_register(&kp_pdev);
3337 platform_device_register(&hs_pdev);
3338
3339 /* configure it as a pdm function*/
3340 if (gpio_tlmm_config(GPIO_CFG(LED_GPIO_PDM, 3,
3341 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
3342 GPIO_CFG_8MA), GPIO_CFG_ENABLE))
3343 pr_err("%s: gpio_tlmm_config for %d failed\n",
3344 __func__, LED_GPIO_PDM);
3345 else
3346 platform_device_register(&led_pdev);
3347
3348#ifdef CONFIG_MSM_RPC_VIBRATOR
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303349 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003350 msm_init_pmic_vibrator();
3351#endif
3352 /*7x25a kgsl initializations*/
3353 msm7x25a_kgsl_3d0_init();
3354}
3355
3356static void __init msm7x2x_init_early(void)
3357{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003358 msm_msm7x2x_allocate_memory_regions();
3359}
3360
3361MACHINE_START(MSM7X27A_RUMI3, "QCT MSM7x27a RUMI3")
3362 .boot_params = PHYS_OFFSET + 0x100,
3363 .map_io = msm_common_io_init,
3364 .reserve = msm7x27a_reserve,
3365 .init_irq = msm_init_irq,
Trilok Soni16f61af2011-07-26 16:06:58 +05303366 .init_machine = msm7627a_rumi3_init,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003367 .timer = &msm_timer,
3368 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303369 .handle_irq = vic_handle_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003370MACHINE_END
3371MACHINE_START(MSM7X27A_SURF, "QCT MSM7x27a SURF")
3372 .boot_params = PHYS_OFFSET + 0x100,
3373 .map_io = msm_common_io_init,
3374 .reserve = msm7x27a_reserve,
3375 .init_irq = msm_init_irq,
3376 .init_machine = msm7x2x_init,
3377 .timer = &msm_timer,
3378 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303379 .handle_irq = vic_handle_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003380MACHINE_END
3381MACHINE_START(MSM7X27A_FFA, "QCT MSM7x27a FFA")
3382 .boot_params = PHYS_OFFSET + 0x100,
3383 .map_io = msm_common_io_init,
3384 .reserve = msm7x27a_reserve,
3385 .init_irq = msm_init_irq,
3386 .init_machine = msm7x2x_init,
3387 .timer = &msm_timer,
3388 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303389 .handle_irq = vic_handle_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003390MACHINE_END
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303391MACHINE_START(MSM7625A_SURF, "QCT MSM7625a SURF")
3392 .boot_params = PHYS_OFFSET + 0x100,
3393 .map_io = msm_common_io_init,
3394 .reserve = msm7x27a_reserve,
3395 .init_irq = msm_init_irq,
3396 .init_machine = msm7x2x_init,
3397 .timer = &msm_timer,
3398 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303399 .handle_irq = vic_handle_irq,
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303400MACHINE_END
3401MACHINE_START(MSM7625A_FFA, "QCT MSM7625a FFA")
3402 .boot_params = PHYS_OFFSET + 0x100,
3403 .map_io = msm_common_io_init,
3404 .reserve = msm7x27a_reserve,
3405 .init_irq = msm_init_irq,
3406 .init_machine = msm7x2x_init,
3407 .timer = &msm_timer,
3408 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303409 .handle_irq = vic_handle_irq,
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303410MACHINE_END