blob: dcb12bb3b85c60785b82d21cb6099008208b7e6a [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"
Chintan Pandyacf467fc2011-12-01 17:11:11 +053057#include "board-msm7627a.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070058
59#define PMEM_KERNEL_EBI1_SIZE 0x3A000
60#define MSM_PMEM_AUDIO_SIZE 0x5B000
61#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
62#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
Rahul Kashyap181d5552011-07-07 10:39:23 +053063#define BAHAMA_SLAVE_ID_FM_REG 0x02
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064#define FM_GPIO 83
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +053065#define BT_PCM_BCLK_MODE 0x88
66#define BT_PCM_DIN_MODE 0x89
67#define BT_PCM_DOUT_MODE 0x8A
68#define BT_PCM_SYNC_MODE 0x8B
69#define FM_I2S_SD_MODE 0x8E
70#define FM_I2S_WS_MODE 0x8F
71#define FM_I2S_SCK_MODE 0x90
72#define I2C_PIN_CTL 0x15
73#define I2C_NORMAL 0x40
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070074
75enum {
76 GPIO_EXPANDER_IRQ_BASE = NR_MSM_IRQS + NR_GPIO_IRQS,
77 GPIO_EXPANDER_GPIO_BASE = NR_MSM_GPIOS,
78 /* SURF expander */
79 GPIO_CORE_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
80 GPIO_BT_SYS_REST_EN = GPIO_CORE_EXPANDER_BASE,
81 GPIO_WLAN_EXT_POR_N,
82 GPIO_DISPLAY_PWR_EN,
83 GPIO_BACKLIGHT_EN,
84 GPIO_PRESSURE_XCLR,
85 GPIO_VREG_S3_EXP,
86 GPIO_UBM2M_PWRDWN,
87 GPIO_ETM_MODE_CS_N,
88 GPIO_HOST_VBUS_EN,
89 GPIO_SPI_MOSI,
90 GPIO_SPI_MISO,
91 GPIO_SPI_CLK,
92 GPIO_SPI_CS0_N,
93 GPIO_CORE_EXPANDER_IO13,
94 GPIO_CORE_EXPANDER_IO14,
95 GPIO_CORE_EXPANDER_IO15,
96 /* Camera expander */
97 GPIO_CAM_EXPANDER_BASE = GPIO_CORE_EXPANDER_BASE + 16,
98 GPIO_CAM_GP_STROBE_READY = GPIO_CAM_EXPANDER_BASE,
99 GPIO_CAM_GP_AFBUSY,
100 GPIO_CAM_GP_CAM_PWDN,
101 GPIO_CAM_GP_CAM1MP_XCLR,
102 GPIO_CAM_GP_CAMIF_RESET_N,
103 GPIO_CAM_GP_STROBE_CE,
104 GPIO_CAM_GP_LED_EN1,
105 GPIO_CAM_GP_LED_EN2,
106};
107
108#if defined(CONFIG_GPIO_SX150X)
109enum {
110 SX150X_CORE,
111 SX150X_CAM,
112};
113
114static struct sx150x_platform_data sx150x_data[] __initdata = {
115 [SX150X_CORE] = {
116 .gpio_base = GPIO_CORE_EXPANDER_BASE,
117 .oscio_is_gpo = false,
118 .io_pullup_ena = 0,
pankaj kumarc5c01392011-08-12 13:44:05 +0530119 .io_pulldn_ena = 0x02,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700120 .io_open_drain_ena = 0xfef8,
121 .irq_summary = -1,
122 },
123 [SX150X_CAM] = {
124 .gpio_base = GPIO_CAM_EXPANDER_BASE,
125 .oscio_is_gpo = false,
126 .io_pullup_ena = 0,
127 .io_pulldn_ena = 0,
128 .io_open_drain_ena = 0x23,
129 .irq_summary = -1,
130 },
131};
132#endif
133
134#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
135
136 /* FM Platform power and shutdown routines */
137#define FPGA_MSM_CNTRL_REG2 0x90008010
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530138static int switch_pcm_i2s_reg_mode(int mode)
139{
140 unsigned char reg = 0;
141 int rc = -1;
142 unsigned char set = I2C_PIN_CTL; /*SET PIN CTL mode*/
143 unsigned char unset = I2C_NORMAL; /* UNSET PIN CTL MODE*/
144 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
145
146 if (mode == 0) {
147 /* as we need to switch path to FM we need to move
148 BT AUX PCM lines to PIN CONTROL mode then move
149 FM to normal mode.*/
150 for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
151 rc = marimba_write(&config, reg, &set, 1);
152 if (rc < 0) {
153 pr_err("pcm pinctl failed = %d", rc);
154 goto err_all;
155 }
156 }
157 for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
158 rc = marimba_write(&config, reg, &unset, 1);
159 if (rc < 0) {
160 pr_err("i2s normal failed = %d", rc);
161 goto err_all;
162 }
163 }
164 } else {
165 /* as we need to switch path to AUXPCM we need to move
166 FM I2S lines to PIN CONTROL mode then move
167 BT AUX_PCM to normal mode.*/
168 for (reg = FM_I2S_SD_MODE; reg <= FM_I2S_SCK_MODE; reg++) {
169 rc = marimba_write(&config, reg, &set, 1);
170 if (rc < 0) {
171 pr_err("i2s pinctl failed = %d", rc);
172 goto err_all;
173 }
174 }
175 for (reg = BT_PCM_BCLK_MODE; reg <= BT_PCM_SYNC_MODE; reg++) {
176 rc = marimba_write(&config, reg, &unset, 1);
177 if (rc < 0) {
178 pr_err("pcm normal failed = %d", rc);
179 goto err_all;
180 }
181 }
182 }
183
184 return 0;
185
186err_all:
187 return rc;
188}
Rahul Kashyap6e669462011-07-23 16:42:56 +0530189
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700190static void config_pcm_i2s_mode(int mode)
191{
192 void __iomem *cfg_ptr;
193 u8 reg2;
194
195 cfg_ptr = ioremap_nocache(FPGA_MSM_CNTRL_REG2, sizeof(char));
196
197 if (!cfg_ptr)
198 return;
199 if (mode) {
200 /*enable the pcm mode in FPGA*/
201 reg2 = readb_relaxed(cfg_ptr);
202 if (reg2 == 0) {
203 reg2 = 1;
204 writeb_relaxed(reg2, cfg_ptr);
205 }
206 } else {
207 /*enable i2s mode in FPGA*/
208 reg2 = readb_relaxed(cfg_ptr);
209 if (reg2 == 1) {
210 reg2 = 0;
211 writeb_relaxed(reg2, cfg_ptr);
212 }
213 }
214 iounmap(cfg_ptr);
215}
216
217static unsigned fm_i2s_config_power_on[] = {
218 /*FM_I2S_SD*/
219 GPIO_CFG(68, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
220 /*FM_I2S_WS*/
221 GPIO_CFG(70, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
222 /*FM_I2S_SCK*/
223 GPIO_CFG(71, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
224};
225
226static unsigned fm_i2s_config_power_off[] = {
227 /*FM_I2S_SD*/
228 GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
229 /*FM_I2S_WS*/
230 GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
231 /*FM_I2S_SCK*/
232 GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
233};
234
235static unsigned bt_config_power_on[] = {
236 /*RFR*/
237 GPIO_CFG(43, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
238 /*CTS*/
239 GPIO_CFG(44, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
240 /*RX*/
241 GPIO_CFG(45, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
242 /*TX*/
243 GPIO_CFG(46, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
244};
245static unsigned bt_config_pcm_on[] = {
246 /*PCM_DOUT*/
247 GPIO_CFG(68, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
248 /*PCM_DIN*/
249 GPIO_CFG(69, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
250 /*PCM_SYNC*/
251 GPIO_CFG(70, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
252 /*PCM_CLK*/
253 GPIO_CFG(71, 1, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
254};
255static unsigned bt_config_power_off[] = {
256 /*RFR*/
257 GPIO_CFG(43, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
258 /*CTS*/
259 GPIO_CFG(44, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
260 /*RX*/
261 GPIO_CFG(45, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
262 /*TX*/
263 GPIO_CFG(46, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
264};
265static unsigned bt_config_pcm_off[] = {
266 /*PCM_DOUT*/
267 GPIO_CFG(68, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
268 /*PCM_DIN*/
269 GPIO_CFG(69, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
270 /*PCM_SYNC*/
271 GPIO_CFG(70, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
272 /*PCM_CLK*/
273 GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
274};
275
276static int config_i2s(int mode)
277{
278 int pin, rc = 0;
279
280 if (mode == FM_I2S_ON) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +0530281 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700282 config_pcm_i2s_mode(0);
283 pr_err("%s mode = FM_I2S_ON", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530284
285 rc = switch_pcm_i2s_reg_mode(0);
286 if (rc) {
287 pr_err("switch mode failed");
288 return rc;
289 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700290 for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_on);
291 pin++) {
292 rc = gpio_tlmm_config(
293 fm_i2s_config_power_on[pin],
294 GPIO_CFG_ENABLE
295 );
296 if (rc < 0)
297 return rc;
298 }
299 } else if (mode == FM_I2S_OFF) {
300 pr_err("%s mode = FM_I2S_OFF", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530301 rc = switch_pcm_i2s_reg_mode(1);
302 if (rc) {
303 pr_err("switch mode failed");
304 return rc;
305 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700306 for (pin = 0; pin < ARRAY_SIZE(fm_i2s_config_power_off);
307 pin++) {
308 rc = gpio_tlmm_config(
309 fm_i2s_config_power_off[pin],
310 GPIO_CFG_ENABLE
311 );
312 if (rc < 0)
313 return rc;
314 }
315 }
316 return rc;
317}
318static int config_pcm(int mode)
319{
320 int pin, rc = 0;
321
322 if (mode == BT_PCM_ON) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +0530323 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700324 config_pcm_i2s_mode(1);
325 pr_err("%s mode =BT_PCM_ON", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530326 rc = switch_pcm_i2s_reg_mode(1);
327 if (rc) {
328 pr_err("switch mode failed");
329 return rc;
330 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700331 for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_on);
332 pin++) {
333 rc = gpio_tlmm_config(bt_config_pcm_on[pin],
334 GPIO_CFG_ENABLE);
335 if (rc < 0)
336 return rc;
337 }
338 } else if (mode == BT_PCM_OFF) {
339 pr_err("%s mode =BT_PCM_OFF", __func__);
Srinivas Krovvidi1cea4d32011-12-06 15:40:56 +0530340 rc = switch_pcm_i2s_reg_mode(0);
341 if (rc) {
342 pr_err("switch mode failed");
343 return rc;
344 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700345 for (pin = 0; pin < ARRAY_SIZE(bt_config_pcm_off);
346 pin++) {
347 rc = gpio_tlmm_config(bt_config_pcm_off[pin],
348 GPIO_CFG_ENABLE);
349 if (rc < 0)
350 return rc;
351 }
352
353 }
354
355 return rc;
356}
357
358static int msm_bahama_setup_pcm_i2s(int mode)
359{
360 int fm_state = 0, bt_state = 0;
361 int rc = 0;
362 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
363
364 fm_state = marimba_get_fm_status(&config);
365 bt_state = marimba_get_bt_status(&config);
366
367 switch (mode) {
368 case BT_PCM_ON:
369 case BT_PCM_OFF:
370 if (!fm_state)
371 rc = config_pcm(mode);
372 break;
373 case FM_I2S_ON:
374 rc = config_i2s(mode);
375 break;
376 case FM_I2S_OFF:
377 if (bt_state)
378 rc = config_pcm(BT_PCM_ON);
379 else
380 rc = config_i2s(mode);
381 break;
382 default:
383 rc = -EIO;
384 pr_err("%s:Unsupported mode", __func__);
385 }
386 return rc;
387}
388
Rahul Kashyap181d5552011-07-07 10:39:23 +0530389static int bt_set_gpio(int on)
390{
391 int rc = 0;
392 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
393
394 if (on) {
395 rc = gpio_direction_output(GPIO_BT_SYS_REST_EN, 1);
396 msleep(100);
397 } else {
398 if (!marimba_get_fm_status(&config) &&
399 !marimba_get_bt_status(&config)) {
400 gpio_set_value_cansleep(GPIO_BT_SYS_REST_EN, 0);
401 rc = gpio_direction_input(GPIO_BT_SYS_REST_EN);
402 msleep(100);
403 }
404 }
405 if (rc)
406 pr_err("%s: BT sys_reset_en GPIO : Error", __func__);
407
408 return rc;
409}
Justin Paupored98328e2011-08-19 13:48:31 -0700410static struct regulator *fm_regulator;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700411static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
412{
413 int rc = 0;
414 const char *id = "FMPW";
415 uint32_t irqcfg;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530416 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
417 u8 value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700418
419 /* Voting for 1.8V Regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700420 fm_regulator = regulator_get(NULL, "msme1");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700421 if (IS_ERR(fm_regulator)) {
Justin Paupored98328e2011-08-19 13:48:31 -0700422 rc = PTR_ERR(fm_regulator);
423 pr_err("%s: could not get regulator: %d\n", __func__, rc);
424 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700425 }
426
427 /* Set the voltage level to 1.8V */
Justin Paupored98328e2011-08-19 13:48:31 -0700428 rc = regulator_set_voltage(fm_regulator, 1800000, 1800000);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700429 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -0700430 pr_err("%s: could not set voltage: %d\n", __func__, rc);
431 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700432 }
433
434 /* Enabling the 1.8V regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700435 rc = regulator_enable(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700436 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -0700437 pr_err("%s: could not enable regulator: %d\n", __func__, rc);
438 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700439 }
440
441 /* Voting for 19.2MHz clock */
442 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
443 PMAPP_CLOCK_VOTE_ON);
444 if (rc < 0) {
445 pr_err("%s: clock vote failed with :(%d)\n",
446 __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700447 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700448 }
449
Rahul Kashyap181d5552011-07-07 10:39:23 +0530450 rc = bt_set_gpio(1);
451 if (rc) {
452 pr_err("%s: bt_set_gpio = %d", __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700453 goto gpio_deconfig;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530454 }
455 /*re-write FM Slave Id, after reset*/
456 value = BAHAMA_SLAVE_ID_FM_ADDR;
457 rc = marimba_write_bit_mask(&config,
458 BAHAMA_SLAVE_ID_FM_REG, &value, 1, 0xFF);
459 if (rc < 0) {
460 pr_err("%s: FM Slave ID rewrite Failed = %d", __func__, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700461 goto gpio_deconfig;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530462 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700463 /* Configuring the FM GPIO */
464 irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
465 GPIO_CFG_2MA);
466
467 rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE);
468 if (rc) {
469 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
470 __func__, irqcfg, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700471 goto gpio_deconfig;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700472 }
473
474 return 0;
475
Justin Paupored98328e2011-08-19 13:48:31 -0700476gpio_deconfig:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700477 pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
478 PMAPP_CLOCK_VOTE_OFF);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530479 bt_set_gpio(0);
Justin Paupored98328e2011-08-19 13:48:31 -0700480reg_disable:
481 regulator_disable(fm_regulator);
482reg_free:
483 regulator_put(fm_regulator);
484 fm_regulator = NULL;
485out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700486 return rc;
487};
488
489static void fm_radio_shutdown(struct marimba_fm_platform_data *pdata)
490{
491 int rc;
492 const char *id = "FMPW";
493
494 /* Releasing the GPIO line used by FM */
495 uint32_t irqcfg = GPIO_CFG(FM_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
496 GPIO_CFG_2MA);
497
498 rc = gpio_tlmm_config(irqcfg, GPIO_CFG_ENABLE);
499 if (rc)
500 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
501 __func__, irqcfg, rc);
502
503 /* Releasing the 1.8V Regulator */
Justin Paupored98328e2011-08-19 13:48:31 -0700504 if (!IS_ERR_OR_NULL(fm_regulator)) {
505 rc = regulator_disable(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700506 if (rc)
Justin Paupored98328e2011-08-19 13:48:31 -0700507 pr_err("%s: could not disable regulator: %d\n",
508 __func__, rc);
509 regulator_put(fm_regulator);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700510 fm_regulator = NULL;
511 }
512
513 /* Voting off the clock */
514 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
515 PMAPP_CLOCK_VOTE_OFF);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700516 if (rc < 0)
517 pr_err("%s: voting off failed with :(%d)\n",
518 __func__, rc);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530519 rc = bt_set_gpio(0);
520 if (rc)
521 pr_err("%s: bt_set_gpio = %d", __func__, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700522}
523
524static struct marimba_fm_platform_data marimba_fm_pdata = {
525 .fm_setup = fm_radio_setup,
526 .fm_shutdown = fm_radio_shutdown,
527 .irq = MSM_GPIO_TO_INT(FM_GPIO),
528 .vreg_s2 = NULL,
529 .vreg_xo_out = NULL,
530 /* Configuring the FM SoC as I2S Master */
531 .is_fm_soc_i2s_master = true,
532 .config_i2s_gpio = msm_bahama_setup_pcm_i2s,
533};
534
Santosh Sajjan6822c682011-07-26 10:49:36 +0530535static struct platform_device msm_wlan_ar6000_pm_device = {
536 .name = "wlan_ar6000_pm_dev",
537 .id = -1,
538};
539
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700540static struct platform_device msm_bt_power_device = {
541 .name = "bt_power",
542};
Rahul Kashyap6e669462011-07-23 16:42:56 +0530543struct bahama_config_register {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700544 u8 reg;
545 u8 value;
546 u8 mask;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700547};
Rahul Kashyap6e669462011-07-23 16:42:56 +0530548struct bt_vreg_info {
549 const char *name;
550 unsigned int pmapp_id;
Pankaj Kumar6ac59af2011-10-12 12:45:40 +0530551 unsigned int min_level;
552 unsigned int max_level;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530553 unsigned int is_pin_controlled;
Justin Paupored98328e2011-08-19 13:48:31 -0700554 struct regulator *reg;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530555};
556static struct bt_vreg_info bt_vregs[] = {
Pankaj Kumar6ac59af2011-10-12 12:45:40 +0530557 {"msme1", 2, 1800000, 1800000, 0, NULL},
Pankaj Kumarb3edc4f2011-12-08 15:40:29 +0530558 {"bt", 21, 2900000, 3300000, 1, NULL}
Rahul Kashyap6e669462011-07-23 16:42:56 +0530559};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700560
561static int bahama_bt(int on)
562{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700563 int rc = 0;
564 int i;
565
566 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
567
568 struct bahama_variant_register {
569 const size_t size;
570 const struct bahama_config_register *set;
571 };
572
573 const struct bahama_config_register *p;
574
575 u8 version;
576
577 const struct bahama_config_register v10_bt_on[] = {
578 { 0xE9, 0x00, 0xFF },
579 { 0xF4, 0x80, 0xFF },
580 { 0xE4, 0x00, 0xFF },
581 { 0xE5, 0x00, 0x0F },
582#ifdef CONFIG_WLAN
583 { 0xE6, 0x38, 0x7F },
584 { 0xE7, 0x06, 0xFF },
585#endif
586 { 0xE9, 0x21, 0xFF },
587 { 0x01, 0x0C, 0x1F },
588 { 0x01, 0x08, 0x1F },
589 };
590
591 const struct bahama_config_register v20_bt_on_fm_off[] = {
592 { 0x11, 0x0C, 0xFF },
593 { 0x13, 0x01, 0xFF },
594 { 0xF4, 0x80, 0xFF },
595 { 0xF0, 0x00, 0xFF },
596 { 0xE9, 0x00, 0xFF },
597#ifdef CONFIG_WLAN
598 { 0x81, 0x00, 0x7F },
599 { 0x82, 0x00, 0xFF },
600 { 0xE6, 0x38, 0x7F },
601 { 0xE7, 0x06, 0xFF },
602#endif
603 { 0x8E, 0x15, 0xFF },
604 { 0x8F, 0x15, 0xFF },
605 { 0x90, 0x15, 0xFF },
606
607 { 0xE9, 0x21, 0xFF },
608 };
609
610 const struct bahama_config_register v20_bt_on_fm_on[] = {
611 { 0x11, 0x0C, 0xFF },
612 { 0x13, 0x01, 0xFF },
613 { 0xF4, 0x86, 0xFF },
614 { 0xF0, 0x06, 0xFF },
615 { 0xE9, 0x00, 0xFF },
616#ifdef CONFIG_WLAN
617 { 0x81, 0x00, 0x7F },
618 { 0x82, 0x00, 0xFF },
619 { 0xE6, 0x38, 0x7F },
620 { 0xE7, 0x06, 0xFF },
621#endif
622 { 0xE9, 0x21, 0xFF },
623 };
624
625 const struct bahama_config_register v10_bt_off[] = {
626 { 0xE9, 0x00, 0xFF },
627 };
628
629 const struct bahama_config_register v20_bt_off_fm_off[] = {
630 { 0xF4, 0x84, 0xFF },
631 { 0xF0, 0x04, 0xFF },
632 { 0xE9, 0x00, 0xFF }
633 };
634
635 const struct bahama_config_register v20_bt_off_fm_on[] = {
636 { 0xF4, 0x86, 0xFF },
637 { 0xF0, 0x06, 0xFF },
638 { 0xE9, 0x00, 0xFF }
639 };
640 const struct bahama_variant_register bt_bahama[2][3] = {
641 {
642 { ARRAY_SIZE(v10_bt_off), v10_bt_off },
643 { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
644 { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
645 },
646 {
647 { ARRAY_SIZE(v10_bt_on), v10_bt_on },
648 { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
649 { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
650 }
651 };
652
653 u8 offset = 0; /* index into bahama configs */
654 on = on ? 1 : 0;
655 version = marimba_read_bahama_ver(&config);
Rahul Kashyap92497af2011-07-07 12:13:52 +0530656 if ((int)version < 0 || version == BAHAMA_VER_UNSUPPORTED) {
657 dev_err(&msm_bt_power_device.dev, "%s: Bahama \
658 version read Error, version = %d \n",
659 __func__, version);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700660 return -EIO;
661 }
662
663 if (version == BAHAMA_VER_2_0) {
664 if (marimba_get_fm_status(&config))
665 offset = 0x01;
666 }
667
668 p = bt_bahama[on][version + offset].set;
669
670 dev_info(&msm_bt_power_device.dev,
671 "%s: found version %d\n", __func__, version);
672
673 for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
674 u8 value = (p+i)->value;
675 rc = marimba_write_bit_mask(&config,
676 (p+i)->reg,
677 &value,
678 sizeof((p+i)->value),
679 (p+i)->mask);
680 if (rc < 0) {
681 dev_err(&msm_bt_power_device.dev,
682 "%s: reg %x write failed: %d\n",
683 __func__, (p+i)->reg, rc);
684 return rc;
685 }
Rahul Kashyap92497af2011-07-07 12:13:52 +0530686 dev_dbg(&msm_bt_power_device.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700687 "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
688 __func__, (p+i)->reg,
689 value, (p+i)->mask);
690 value = 0;
691 rc = marimba_read_bit_mask(&config,
692 (p+i)->reg, &value,
693 sizeof((p+i)->value), (p+i)->mask);
694 if (rc < 0)
695 dev_err(&msm_bt_power_device.dev, "%s marimba_read_bit_mask- error",
696 __func__);
Rahul Kashyap92497af2011-07-07 12:13:52 +0530697 dev_dbg(&msm_bt_power_device.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700698 "%s: reg 0x%02x read value 0x%02x mask 0x%02x\n",
699 __func__, (p+i)->reg,
700 value, (p+i)->mask);
701 }
702 /* Update BT Status */
703 if (on)
704 marimba_set_bt_status(&config, true);
705 else
706 marimba_set_bt_status(&config, false);
707 return rc;
708}
709static int bluetooth_switch_regulators(int on)
710{
711 int i, rc = 0;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530712 const char *id = "BTPW";
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700713
Rahul Kashyap6e669462011-07-23 16:42:56 +0530714 for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
Justin Paupored98328e2011-08-19 13:48:31 -0700715 if (IS_ERR_OR_NULL(bt_vregs[i].reg)) {
716 rc = bt_vregs[i].reg ?
717 PTR_ERR(bt_vregs[i].reg) :
718 -ENODEV;
719 dev_err(&msm_bt_power_device.dev,
720 "%s: invalid regulator handle for %s: %d\n",
721 __func__, bt_vregs[i].name, rc);
722 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700723 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700724
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530725 rc = on ? regulator_set_voltage(bt_vregs[i].reg,
Pankaj Kumar6ac59af2011-10-12 12:45:40 +0530726 bt_vregs[i].min_level,
727 bt_vregs[i].max_level) : 0;
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530728 if (rc) {
729 dev_err(&msm_bt_power_device.dev,
730 "%s: could not set voltage for %s: %d\n",
731 __func__, bt_vregs[i].name, rc);
732 goto reg_disable;
733 }
734
735 rc = on ? regulator_enable(bt_vregs[i].reg) : 0;
736 if (rc) {
737 dev_err(&msm_bt_power_device.dev,
738 "%s: could not %sable regulator %s: %d\n",
739 __func__, "en", bt_vregs[i].name, rc);
740 goto reg_disable;
741 }
742
Justin Paupored98328e2011-08-19 13:48:31 -0700743 if (bt_vregs[i].is_pin_controlled) {
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530744 rc = pmapp_vreg_lpm_pincntrl_vote(id,
Rahul Kashyap6e669462011-07-23 16:42:56 +0530745 bt_vregs[i].pmapp_id,
746 PMAPP_CLOCK_ID_D1,
747 on ? PMAPP_CLOCK_VOTE_ON :
Justin Paupored98328e2011-08-19 13:48:31 -0700748 PMAPP_CLOCK_VOTE_OFF);
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530749 if (rc) {
750 dev_err(&msm_bt_power_device.dev,
751 "%s: pin control failed for %s: %d\n",
752 __func__, bt_vregs[i].name, rc);
753 goto pin_cnt_fail;
754 }
Rahul Kashyap6e669462011-07-23 16:42:56 +0530755 }
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530756 rc = on ? 0 : regulator_disable(bt_vregs[i].reg);
Justin Paupored98328e2011-08-19 13:48:31 -0700757
758 if (rc) {
759 dev_err(&msm_bt_power_device.dev,
760 "%s: could not %sable regulator %s: %d\n",
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530761 __func__, "dis", bt_vregs[i].name, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700762 goto reg_disable;
Rahul Kashyap6e669462011-07-23 16:42:56 +0530763 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700764 }
Rahul Kashyap6e669462011-07-23 16:42:56 +0530765
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700766 return rc;
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530767pin_cnt_fail:
768 if (on)
769 regulator_disable(bt_vregs[i].reg);
Justin Paupored98328e2011-08-19 13:48:31 -0700770reg_disable:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530771 while (i) {
772 if (on) {
773 i--;
774 regulator_disable(bt_vregs[i].reg);
775 regulator_put(bt_vregs[i].reg);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700776 }
Justin Paupored98328e2011-08-19 13:48:31 -0700777 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700778 return rc;
779}
780
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530781static struct regulator *reg_s3;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700782static unsigned int msm_bahama_setup_power(void)
783{
784 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700785
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530786 reg_s3 = regulator_get(NULL, "msme1");
787 if (IS_ERR(reg_s3)) {
788 rc = PTR_ERR(reg_s3);
Justin Paupored98328e2011-08-19 13:48:31 -0700789 pr_err("%s: could not get regulator: %d\n", __func__, rc);
790 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700791 }
Justin Paupored98328e2011-08-19 13:48:31 -0700792
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530793 rc = regulator_set_voltage(reg_s3, 1800000, 1800000);
Justin Paupored98328e2011-08-19 13:48:31 -0700794 if (rc) {
795 pr_err("%s: could not set voltage: %d\n", __func__, rc);
796 goto reg_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700797 }
Justin Paupored98328e2011-08-19 13:48:31 -0700798
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530799 rc = regulator_enable(reg_s3);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700800 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -0700801 pr_err("%s: could not enable regulator: %d\n", __func__, rc);
802 goto reg_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700803 }
804
805 /*setup Bahama_sys_reset_n*/
806 rc = gpio_request(GPIO_BT_SYS_REST_EN, "bahama sys_rst_n");
Justin Paupored98328e2011-08-19 13:48:31 -0700807 if (rc) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700808 pr_err("%s: gpio_request %d = %d\n", __func__,
809 GPIO_BT_SYS_REST_EN, rc);
Justin Paupored98328e2011-08-19 13:48:31 -0700810 goto reg_disable;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700811 }
Justin Paupored98328e2011-08-19 13:48:31 -0700812
Rahul Kashyap181d5552011-07-07 10:39:23 +0530813 rc = bt_set_gpio(1);
Justin Paupored98328e2011-08-19 13:48:31 -0700814 if (rc) {
Rahul Kashyap181d5552011-07-07 10:39:23 +0530815 pr_err("%s: bt_set_gpio %d = %d\n", __func__,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700816 GPIO_BT_SYS_REST_EN, rc);
817 goto gpio_fail;
818 }
Justin Paupored98328e2011-08-19 13:48:31 -0700819
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700820 return rc;
821
822gpio_fail:
823 gpio_free(GPIO_BT_SYS_REST_EN);
Justin Paupored98328e2011-08-19 13:48:31 -0700824reg_disable:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530825 regulator_disable(reg_s3);
Justin Paupored98328e2011-08-19 13:48:31 -0700826reg_fail:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530827 regulator_put(reg_s3);
Justin Paupored98328e2011-08-19 13:48:31 -0700828out:
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530829 reg_s3 = NULL;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700830 return rc;
831}
832
833static unsigned int msm_bahama_shutdown_power(int value)
834{
835 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700836
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530837 if (IS_ERR_OR_NULL(reg_s3)) {
838 rc = reg_s3 ? PTR_ERR(reg_s3) : -ENODEV;
Justin Paupored98328e2011-08-19 13:48:31 -0700839 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700840 }
Justin Paupored98328e2011-08-19 13:48:31 -0700841
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530842 rc = regulator_disable(reg_s3);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700843 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -0700844 pr_err("%s: could not disable regulator: %d\n", __func__, rc);
845 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700846 }
Justin Paupored98328e2011-08-19 13:48:31 -0700847
Rahul Kashyape8698c62011-07-20 20:43:05 +0530848 if (value == BAHAMA_ID) {
849 rc = bt_set_gpio(0);
850 if (rc) {
851 pr_err("%s: bt_set_gpio = %d\n",
852 __func__, rc);
853 }
Justin Paupored98328e2011-08-19 13:48:31 -0700854 gpio_free(GPIO_BT_SYS_REST_EN);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530855 }
Justin Paupored98328e2011-08-19 13:48:31 -0700856
Pankaj Kumara9d576c2011-09-29 10:56:53 +0530857 regulator_put(reg_s3);
858 reg_s3 = NULL;
Justin Paupored98328e2011-08-19 13:48:31 -0700859
860 return 0;
861
Justin Paupored98328e2011-08-19 13:48:31 -0700862out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700863 return rc;
864}
865
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700866static unsigned int msm_bahama_core_config(int type)
867{
868 int rc = 0;
869
870 if (type == BAHAMA_ID) {
871 int i;
Rahul Kashyap181d5552011-07-07 10:39:23 +0530872 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700873 const struct bahama_config_register v20_init[] = {
874 /* reg, value, mask */
875 { 0xF4, 0x84, 0xFF }, /* AREG */
876 { 0xF0, 0x04, 0xFF } /* DREG */
877 };
878 if (marimba_read_bahama_ver(&config) == BAHAMA_VER_2_0) {
879 for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
880 u8 value = v20_init[i].value;
881 rc = marimba_write_bit_mask(&config,
882 v20_init[i].reg,
883 &value,
884 sizeof(v20_init[i].value),
885 v20_init[i].mask);
886 if (rc < 0) {
887 pr_err("%s: reg %d write failed: %d\n",
888 __func__, v20_init[i].reg, rc);
889 return rc;
890 }
891 pr_debug("%s: reg 0x%02x value 0x%02x"
892 " mask 0x%02x\n",
893 __func__, v20_init[i].reg,
894 v20_init[i].value, v20_init[i].mask);
895 }
896 }
897 }
Rahul Kashyap181d5552011-07-07 10:39:23 +0530898 rc = bt_set_gpio(0);
899 if (rc) {
900 pr_err("%s: bt_set_gpio = %d\n",
901 __func__, rc);
902 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700903 pr_debug("core type: %d\n", type);
904 return rc;
905}
906
907static int bluetooth_power(int on)
908{
909 int pin, rc = 0;
910 const char *id = "BTPW";
911 int cid = 0;
912
913 cid = adie_get_detected_connectivity_type();
914 if (cid != BAHAMA_ID) {
915 pr_err("%s: unexpected adie connectivity type: %d\n",
916 __func__, cid);
917 return -ENODEV;
918 }
919 if (on) {
920 /*setup power for BT SOC*/
Rahul Kashyap181d5552011-07-07 10:39:23 +0530921 rc = bt_set_gpio(on);
922 if (rc) {
923 pr_err("%s: bt_set_gpio = %d\n",
924 __func__, rc);
925 goto exit;
926 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700927 rc = bluetooth_switch_regulators(on);
928 if (rc < 0) {
929 pr_err("%s: bluetooth_switch_regulators rc = %d",
930 __func__, rc);
931 goto exit;
932 }
933 /*setup BT GPIO lines*/
934 for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on);
935 pin++) {
936 rc = gpio_tlmm_config(bt_config_power_on[pin],
937 GPIO_CFG_ENABLE);
938 if (rc < 0) {
939 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
940 __func__,
941 bt_config_power_on[pin],
942 rc);
943 goto fail_power;
944 }
945 }
946 /*Setup BT clocks*/
947 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
948 PMAPP_CLOCK_VOTE_ON);
949 if (rc < 0) {
950 pr_err("Failed to vote for TCXO_D1 ON\n");
951 goto fail_clock;
952 }
953 msleep(20);
954
955 /*I2C config for Bahama*/
956 rc = bahama_bt(1);
957 if (rc < 0) {
958 pr_err("%s: bahama_bt rc = %d", __func__, rc);
959 goto fail_i2c;
960 }
961 msleep(20);
962
963 /*setup BT PCM lines*/
964 rc = msm_bahama_setup_pcm_i2s(BT_PCM_ON);
965 if (rc < 0) {
966 pr_err("%s: msm_bahama_setup_pcm_i2s , rc =%d\n",
967 __func__, rc);
968 goto fail_power;
969 }
970 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
971 PMAPP_CLOCK_VOTE_PIN_CTRL);
972 if (rc < 0)
973 pr_err("%s:Pin Control Failed, rc = %d",
974 __func__, rc);
975
976 } else {
977 rc = bahama_bt(0);
978 if (rc < 0)
979 pr_err("%s: bahama_bt rc = %d", __func__, rc);
Rahul Kashyap181d5552011-07-07 10:39:23 +0530980
981 rc = bt_set_gpio(on);
982 if (rc) {
983 pr_err("%s: bt_set_gpio = %d\n",
984 __func__, rc);
985 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700986fail_i2c:
987 rc = pmapp_clock_vote(id, PMAPP_CLOCK_ID_D1,
988 PMAPP_CLOCK_VOTE_OFF);
989 if (rc < 0)
990 pr_err("%s: Failed to vote Off D1\n", __func__);
991fail_clock:
992 for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off);
993 pin++) {
994 rc = gpio_tlmm_config(bt_config_power_off[pin],
995 GPIO_CFG_ENABLE);
996 if (rc < 0) {
997 pr_err("%s: gpio_tlmm_config(%#x)=%d\n",
998 __func__, bt_config_power_off[pin], rc);
999 }
1000 }
1001 rc = msm_bahama_setup_pcm_i2s(BT_PCM_OFF);
1002 if (rc < 0) {
1003 pr_err("%s: msm_bahama_setup_pcm_i2s, rc =%d\n",
1004 __func__, rc);
1005 }
1006fail_power:
1007 rc = bluetooth_switch_regulators(0);
1008 if (rc < 0) {
1009 pr_err("%s: switch_regulators : rc = %d",\
1010 __func__, rc);
1011 goto exit;
1012 }
1013 }
1014 return rc;
1015exit:
1016 pr_err("%s: failed with rc = %d", __func__, rc);
1017 return rc;
1018}
1019
1020static int __init bt_power_init(void)
1021{
1022 int i, rc = 0;
Justin Paupored98328e2011-08-19 13:48:31 -07001023 struct device *dev = &msm_bt_power_device.dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001024
Justin Paupored98328e2011-08-19 13:48:31 -07001025 for (i = 0; i < ARRAY_SIZE(bt_vregs); i++) {
1026 bt_vregs[i].reg = regulator_get(dev, bt_vregs[i].name);
1027 if (IS_ERR(bt_vregs[i].reg)) {
1028 rc = PTR_ERR(bt_vregs[i].reg);
1029 dev_err(dev, "%s: could not get regulator %s: %d\n",
1030 __func__, bt_vregs[i].name, rc);
1031 goto reg_get_fail;
1032 }
Justin Paupored98328e2011-08-19 13:48:31 -07001033 }
1034
1035 dev->platform_data = &bluetooth_power;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001036
1037 return rc;
1038
Justin Paupored98328e2011-08-19 13:48:31 -07001039reg_get_fail:
1040 while (i--) {
1041 regulator_put(bt_vregs[i].reg);
1042 bt_vregs[i].reg = NULL;
1043 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001044 return rc;
1045}
1046
1047static struct marimba_platform_data marimba_pdata = {
1048 .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,
1049 .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
1050 .bahama_setup = msm_bahama_setup_power,
1051 .bahama_shutdown = msm_bahama_shutdown_power,
1052 .bahama_core_config = msm_bahama_core_config,
1053 .fm = &marimba_fm_pdata,
1054};
1055
1056#endif
1057
1058#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
1059static struct i2c_board_info core_exp_i2c_info[] __initdata = {
1060 {
1061 I2C_BOARD_INFO("sx1509q", 0x3e),
1062 },
1063};
1064static struct i2c_board_info cam_exp_i2c_info[] __initdata = {
1065 {
1066 I2C_BOARD_INFO("sx1508q", 0x22),
1067 .platform_data = &sx150x_data[SX150X_CAM],
1068 },
1069};
1070#endif
1071#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
1072static struct i2c_board_info bahama_devices[] = {
1073{
1074 I2C_BOARD_INFO("marimba", 0xc),
1075 .platform_data = &marimba_pdata,
1076},
1077};
1078#endif
1079
1080#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
1081static void __init register_i2c_devices(void)
1082{
1083
1084 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
1085 cam_exp_i2c_info,
1086 ARRAY_SIZE(cam_exp_i2c_info));
1087
Trilok Soni3d0f6c52011-07-26 16:06:58 +05301088 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001089 sx150x_data[SX150X_CORE].io_open_drain_ena = 0xe0f0;
1090
1091 core_exp_i2c_info[0].platform_data =
1092 &sx150x_data[SX150X_CORE];
1093
1094 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
1095 core_exp_i2c_info,
1096 ARRAY_SIZE(core_exp_i2c_info));
1097#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
1098 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
1099 bahama_devices,
1100 ARRAY_SIZE(bahama_devices));
1101#endif
1102}
1103#endif
1104
1105static struct msm_gpio qup_i2c_gpios_io[] = {
1106 { GPIO_CFG(60, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1107 "qup_scl" },
1108 { GPIO_CFG(61, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1109 "qup_sda" },
1110 { GPIO_CFG(131, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1111 "qup_scl" },
1112 { GPIO_CFG(132, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1113 "qup_sda" },
1114};
1115
1116static struct msm_gpio qup_i2c_gpios_hw[] = {
1117 { GPIO_CFG(60, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1118 "qup_scl" },
1119 { GPIO_CFG(61, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1120 "qup_sda" },
1121 { GPIO_CFG(131, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1122 "qup_scl" },
1123 { GPIO_CFG(132, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
1124 "qup_sda" },
1125};
1126
1127static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
1128{
1129 int rc;
1130
1131 if (adap_id < 0 || adap_id > 1)
1132 return;
1133
1134 /* Each adapter gets 2 lines from the table */
1135 if (config_type)
1136 rc = msm_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
1137 else
1138 rc = msm_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
1139 if (rc < 0)
1140 pr_err("QUP GPIO request/enable failed: %d\n", rc);
1141}
1142
1143static struct msm_i2c_platform_data msm_gsbi0_qup_i2c_pdata = {
1144 .clk_freq = 100000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001145 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
1146};
1147
1148static struct msm_i2c_platform_data msm_gsbi1_qup_i2c_pdata = {
1149 .clk_freq = 100000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001150 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
1151};
1152
1153#ifdef CONFIG_ARCH_MSM7X27A
Neti Ravi Kumar061726e2011-12-08 15:14:57 +05301154#define MSM_PMEM_MDP_SIZE 0x2300000
1155#define MSM7x25A_MSM_PMEM_MDP_SIZE 0x1500000
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301156
Roja Rani Yarubandi09986562011-12-06 18:54:47 +05301157#define MSM_PMEM_ADSP_SIZE 0x1000000
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301158#define MSM7x25A_MSM_PMEM_ADSP_SIZE 0xB91000
1159
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001160
1161#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301162#define MSM_FB_SIZE 0x260000
1163#define MSM7x25A_MSM_FB_SIZE 0xE1000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001164#else
Jeevan Shriramf40764e2011-10-31 23:28:26 +05301165#define MSM_FB_SIZE 0x195000
1166#define MSM7x25A_MSM_FB_SIZE 0xE1000
1167
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001168#endif
1169
1170#endif
1171
1172static struct android_usb_platform_data android_usb_pdata = {
1173 .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
1174};
1175
1176static struct platform_device android_usb_device = {
1177 .name = "android_usb",
1178 .id = -1,
1179 .dev = {
1180 .platform_data = &android_usb_pdata,
1181 },
1182};
1183
1184#ifdef CONFIG_USB_EHCI_MSM_72K
1185static void msm_hsusb_vbus_power(unsigned phy_info, int on)
1186{
1187 int rc = 0;
1188 unsigned gpio;
1189
1190 gpio = GPIO_HOST_VBUS_EN;
1191
1192 rc = gpio_request(gpio, "i2c_host_vbus_en");
1193 if (rc < 0) {
1194 pr_err("failed to request %d GPIO\n", gpio);
1195 return;
1196 }
1197 gpio_direction_output(gpio, !!on);
1198 gpio_set_value_cansleep(gpio, !!on);
1199 gpio_free(gpio);
1200}
1201
1202static struct msm_usb_host_platform_data msm_usb_host_pdata = {
1203 .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_45NM),
1204};
1205
1206static void __init msm7x2x_init_host(void)
1207{
1208 msm_add_host(0, &msm_usb_host_pdata);
1209}
1210#endif
1211
1212#ifdef CONFIG_USB_MSM_OTG_72K
1213static int hsusb_rpc_connect(int connect)
1214{
1215 if (connect)
1216 return msm_hsusb_rpc_connect();
1217 else
1218 return msm_hsusb_rpc_close();
1219}
1220
Justin Paupored98328e2011-08-19 13:48:31 -07001221static struct regulator *reg_hsusb;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001222static int msm_hsusb_ldo_init(int init)
1223{
Justin Paupored98328e2011-08-19 13:48:31 -07001224 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001225
Justin Paupored98328e2011-08-19 13:48:31 -07001226 if (init) {
1227 reg_hsusb = regulator_get(NULL, "usb");
1228 if (IS_ERR(reg_hsusb)) {
1229 rc = PTR_ERR(reg_hsusb);
1230 pr_err("%s: could not get regulator: %d\n",
1231 __func__, rc);
1232 goto out;
1233 }
1234
1235 rc = regulator_set_voltage(reg_hsusb, 3300000, 3300000);
1236 if (rc) {
1237 pr_err("%s: could not set voltage: %d\n",
1238 __func__, rc);
1239 goto reg_free;
1240 }
1241
1242 return 0;
1243 }
1244 /* else fall through */
1245reg_free:
1246 regulator_put(reg_hsusb);
1247out:
1248 reg_hsusb = NULL;
1249 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001250}
1251
1252static int msm_hsusb_ldo_enable(int enable)
1253{
1254 static int ldo_status;
1255
Justin Paupored98328e2011-08-19 13:48:31 -07001256 if (IS_ERR_OR_NULL(reg_hsusb))
1257 return reg_hsusb ? PTR_ERR(reg_hsusb) : -ENODEV;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001258
1259 if (ldo_status == enable)
1260 return 0;
1261
1262 ldo_status = enable;
1263
Justin Paupored98328e2011-08-19 13:48:31 -07001264 return enable ?
1265 regulator_enable(reg_hsusb) :
1266 regulator_disable(reg_hsusb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001267}
1268
1269#ifndef CONFIG_USB_EHCI_MSM_72K
1270static int msm_hsusb_pmic_notif_init(void (*callback)(int online), int init)
1271{
1272 int ret = 0;
1273
1274 if (init)
1275 ret = msm_pm_app_rpc_init(callback);
1276 else
1277 msm_pm_app_rpc_deinit(callback);
1278
1279 return ret;
1280}
1281#endif
1282
1283static struct msm_otg_platform_data msm_otg_pdata = {
1284#ifndef CONFIG_USB_EHCI_MSM_72K
1285 .pmic_vbus_notif_init = msm_hsusb_pmic_notif_init,
1286#else
1287 .vbus_power = msm_hsusb_vbus_power,
1288#endif
1289 .rpc_connect = hsusb_rpc_connect,
1290 .core_clk = 1,
1291 .pemp_level = PRE_EMPHASIS_WITH_20_PERCENT,
1292 .cdr_autoreset = CDR_AUTO_RESET_DISABLE,
1293 .drv_ampl = HS_DRV_AMPLITUDE_DEFAULT,
1294 .se1_gating = SE1_GATING_DISABLE,
1295 .ldo_init = msm_hsusb_ldo_init,
1296 .ldo_enable = msm_hsusb_ldo_enable,
1297 .chg_init = hsusb_chg_init,
1298 .chg_connected = hsusb_chg_connected,
1299 .chg_vbus_draw = hsusb_chg_vbus_draw,
1300};
1301#endif
1302
1303static struct msm_hsusb_gadget_platform_data msm_gadget_pdata = {
1304 .is_phy_status_timer_on = 1,
1305};
1306
1307static struct resource smc91x_resources[] = {
1308 [0] = {
1309 .start = 0x90000300,
1310 .end = 0x900003ff,
1311 .flags = IORESOURCE_MEM,
1312 },
1313 [1] = {
1314 .start = MSM_GPIO_TO_INT(4),
1315 .end = MSM_GPIO_TO_INT(4),
1316 .flags = IORESOURCE_IRQ,
1317 },
1318};
1319
1320static struct platform_device smc91x_device = {
1321 .name = "smc91x",
1322 .id = 0,
1323 .num_resources = ARRAY_SIZE(smc91x_resources),
1324 .resource = smc91x_resources,
1325};
1326
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001327#ifdef CONFIG_SERIAL_MSM_HS
1328static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = {
1329 .inject_rx_on_wakeup = 1,
1330 .rx_to_inject = 0xFD,
1331};
1332#endif
1333static struct msm_pm_platform_data msm7x27a_pm_data[MSM_PM_SLEEP_MODE_NR] = {
1334 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE] = {
1335 .idle_supported = 1,
1336 .suspend_supported = 1,
1337 .idle_enabled = 1,
1338 .suspend_enabled = 1,
1339 .latency = 16000,
1340 .residency = 20000,
1341 },
1342 [MSM_PM_SLEEP_MODE_POWER_COLLAPSE_NO_XO_SHUTDOWN] = {
1343 .idle_supported = 1,
1344 .suspend_supported = 1,
1345 .idle_enabled = 1,
1346 .suspend_enabled = 1,
1347 .latency = 12000,
1348 .residency = 20000,
1349 },
1350 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT] = {
1351 .idle_supported = 1,
1352 .suspend_supported = 1,
1353 .idle_enabled = 0,
1354 .suspend_enabled = 1,
1355 .latency = 2000,
1356 .residency = 0,
1357 },
1358 [MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT] = {
1359 .idle_supported = 1,
1360 .suspend_supported = 1,
1361 .idle_enabled = 1,
1362 .suspend_enabled = 1,
1363 .latency = 2,
1364 .residency = 0,
1365 },
1366};
1367
Maheshkumar Sivasubramanianc6c55032011-10-25 16:01:32 -06001368static struct msm_pm_boot_platform_data msm_pm_boot_pdata __initdata = {
1369 .mode = MSM_PM_BOOT_CONFIG_RESET_VECTOR_VIRT,
1370 .v_addr = (uint32_t *)PAGE_OFFSET,
1371};
1372
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001373static struct android_pmem_platform_data android_pmem_adsp_pdata = {
1374 .name = "pmem_adsp",
1375 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
Mahesh Lankac6af7eb2011-08-02 18:00:35 +05301376 .cached = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001377 .memory_type = MEMTYPE_EBI1,
1378};
1379
1380static struct platform_device android_pmem_adsp_device = {
1381 .name = "android_pmem",
1382 .id = 1,
1383 .dev = { .platform_data = &android_pmem_adsp_pdata },
1384};
1385
1386static unsigned pmem_mdp_size = MSM_PMEM_MDP_SIZE;
1387static int __init pmem_mdp_size_setup(char *p)
1388{
1389 pmem_mdp_size = memparse(p, NULL);
1390 return 0;
1391}
1392
1393early_param("pmem_mdp_size", pmem_mdp_size_setup);
1394
1395static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
1396static int __init pmem_adsp_size_setup(char *p)
1397{
1398 pmem_adsp_size = memparse(p, NULL);
1399 return 0;
1400}
1401
1402early_param("pmem_adsp_size", pmem_adsp_size_setup);
1403
1404static unsigned fb_size = MSM_FB_SIZE;
1405static int __init fb_size_setup(char *p)
1406{
1407 fb_size = memparse(p, NULL);
1408 return 0;
1409}
1410
1411early_param("fb_size", fb_size_setup);
1412
Justin Paupored98328e2011-08-19 13:48:31 -07001413static struct regulator_bulk_data regs_lcdc[] = {
1414 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
1415 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001416};
1417
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001418static uint32_t lcdc_gpio_initialized;
1419
1420static void lcdc_toshiba_gpio_init(void)
1421{
Justin Paupored98328e2011-08-19 13:48:31 -07001422 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001423 if (!lcdc_gpio_initialized) {
1424 if (gpio_request(GPIO_SPI_CLK, "spi_clk")) {
1425 pr_err("failed to request gpio spi_clk\n");
1426 return;
1427 }
1428 if (gpio_request(GPIO_SPI_CS0_N, "spi_cs")) {
1429 pr_err("failed to request gpio spi_cs0_N\n");
1430 goto fail_gpio6;
1431 }
1432 if (gpio_request(GPIO_SPI_MOSI, "spi_mosi")) {
1433 pr_err("failed to request gpio spi_mosi\n");
1434 goto fail_gpio5;
1435 }
1436 if (gpio_request(GPIO_SPI_MISO, "spi_miso")) {
1437 pr_err("failed to request gpio spi_miso\n");
1438 goto fail_gpio4;
1439 }
1440 if (gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr")) {
1441 pr_err("failed to request gpio_disp_pwr\n");
1442 goto fail_gpio3;
1443 }
1444 if (gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en")) {
1445 pr_err("failed to request gpio_bkl_en\n");
1446 goto fail_gpio2;
1447 }
1448 pmapp_disp_backlight_init();
1449
Justin Paupored98328e2011-08-19 13:48:31 -07001450 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_lcdc), regs_lcdc);
1451 if (rc) {
1452 pr_err("%s: could not get regulators: %d\n",
1453 __func__, rc);
1454 goto fail_gpio1;
1455 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001456
Justin Paupored98328e2011-08-19 13:48:31 -07001457 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_lcdc),
1458 regs_lcdc);
1459 if (rc) {
1460 pr_err("%s: could not set voltages: %d\n",
1461 __func__, rc);
1462 goto fail_vreg;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001463 }
1464 lcdc_gpio_initialized = 1;
1465 }
1466 return;
Justin Paupored98328e2011-08-19 13:48:31 -07001467fail_vreg:
1468 regulator_bulk_free(ARRAY_SIZE(regs_lcdc), regs_lcdc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001469fail_gpio1:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001470 gpio_free(GPIO_BACKLIGHT_EN);
1471fail_gpio2:
1472 gpio_free(GPIO_DISPLAY_PWR_EN);
1473fail_gpio3:
1474 gpio_free(GPIO_SPI_MISO);
1475fail_gpio4:
1476 gpio_free(GPIO_SPI_MOSI);
1477fail_gpio5:
1478 gpio_free(GPIO_SPI_CS0_N);
1479fail_gpio6:
1480 gpio_free(GPIO_SPI_CLK);
1481 lcdc_gpio_initialized = 0;
1482}
1483
1484static uint32_t lcdc_gpio_table[] = {
1485 GPIO_SPI_CLK,
1486 GPIO_SPI_CS0_N,
1487 GPIO_SPI_MOSI,
1488 GPIO_DISPLAY_PWR_EN,
1489 GPIO_BACKLIGHT_EN,
1490 GPIO_SPI_MISO,
1491};
1492
1493static void config_lcdc_gpio_table(uint32_t *table, int len, unsigned enable)
1494{
1495 int n;
1496
1497 if (lcdc_gpio_initialized) {
1498 /* All are IO Expander GPIOs */
1499 for (n = 0; n < (len - 1); n++)
1500 gpio_direction_output(table[n], 1);
1501 }
1502}
1503
1504static void lcdc_toshiba_config_gpios(int enable)
1505{
1506 config_lcdc_gpio_table(lcdc_gpio_table,
1507 ARRAY_SIZE(lcdc_gpio_table), enable);
1508}
1509
1510static int msm_fb_lcdc_power_save(int on)
1511{
Justin Paupored98328e2011-08-19 13:48:31 -07001512 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001513 /* Doing the init of the LCDC GPIOs very late as they are from
1514 an I2C-controlled IO Expander */
1515 lcdc_toshiba_gpio_init();
1516
1517 if (lcdc_gpio_initialized) {
1518 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
1519 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
1520
Justin Paupored98328e2011-08-19 13:48:31 -07001521 rc = on ? regulator_bulk_enable(
1522 ARRAY_SIZE(regs_lcdc), regs_lcdc) :
1523 regulator_bulk_disable(
1524 ARRAY_SIZE(regs_lcdc), regs_lcdc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001525
Justin Paupored98328e2011-08-19 13:48:31 -07001526 if (rc)
1527 pr_err("%s: could not %sable regulators: %d\n",
1528 __func__, on ? "en" : "dis", rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001529 }
1530
1531 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001532}
1533
1534
1535static int lcdc_toshiba_set_bl(int level)
1536{
1537 int ret;
1538
1539 ret = pmapp_disp_backlight_set_brightness(level);
1540 if (ret)
1541 pr_err("%s: can't set lcd backlight!\n", __func__);
1542
1543 return ret;
1544}
1545
1546
1547static struct lcdc_platform_data lcdc_pdata = {
Jeevan Shriram15f2a5e2011-07-13 21:45:26 +05301548 .lcdc_gpio_config = NULL,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001549 .lcdc_power_save = msm_fb_lcdc_power_save,
1550};
1551
1552static int lcd_panel_spi_gpio_num[] = {
1553 GPIO_SPI_MOSI, /* spi_sdi */
1554 GPIO_SPI_MISO, /* spi_sdoi */
1555 GPIO_SPI_CLK, /* spi_clk */
1556 GPIO_SPI_CS0_N, /* spi_cs */
1557};
1558
1559static struct msm_panel_common_pdata lcdc_toshiba_panel_data = {
1560 .panel_config_gpio = lcdc_toshiba_config_gpios,
1561 .pmic_backlight = lcdc_toshiba_set_bl,
1562 .gpio_num = lcd_panel_spi_gpio_num,
1563};
1564
1565static struct platform_device lcdc_toshiba_panel_device = {
1566 .name = "lcdc_toshiba_fwvga_pt",
1567 .id = 0,
1568 .dev = {
1569 .platform_data = &lcdc_toshiba_panel_data,
1570 }
1571};
1572
1573static struct resource msm_fb_resources[] = {
1574 {
1575 .flags = IORESOURCE_DMA,
1576 }
1577};
1578
Ajay Singh Parmareede70e2011-08-24 17:36:08 +05301579#define PANEL_NAME_MAX_LEN 30
1580#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
1581#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
1582
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001583static int msm_fb_detect_panel(const char *name)
1584{
Taniya Das0a5303a2011-08-23 18:47:48 +05301585 int ret = -ENODEV;
1586
1587 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
1588 if (!strncmp(name, "lcdc_toshiba_fwvga_pt", 21) ||
1589 !strncmp(name, "mipi_cmd_renesas_fwvga", 22))
1590 ret = 0;
Jeevan Shriram29c9e952011-10-27 11:22:46 +05301591 } else if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()) {
Taniya Das0a5303a2011-08-23 18:47:48 +05301592 if (!strncmp(name, "mipi_cmd_renesas_fwvga", 22))
1593 ret = 0;
1594 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001595
Ajay Singh Parmareede70e2011-08-24 17:36:08 +05301596#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
1597 !defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
1598 !defined(CONFIG_FB_MSM_LCDC_MIPI_PANEL_AUTO_DETECT)
1599 if (machine_is_msm7x27a_surf() ||
1600 machine_is_msm7625a_surf()) {
1601 if (!strncmp(name, LCDC_TOSHIBA_FWVGA_PANEL_NAME,
1602 strnlen(LCDC_TOSHIBA_FWVGA_PANEL_NAME,
1603 PANEL_NAME_MAX_LEN)))
1604 return 0;
1605 }
1606#endif
Taniya Das0a5303a2011-08-23 18:47:48 +05301607 return ret;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001608}
1609
1610static struct msm_fb_platform_data msm_fb_pdata = {
1611 .detect_client = msm_fb_detect_panel,
1612};
1613
1614static struct platform_device msm_fb_device = {
1615 .name = "msm_fb",
1616 .id = 0,
1617 .num_resources = ARRAY_SIZE(msm_fb_resources),
1618 .resource = msm_fb_resources,
1619 .dev = {
1620 .platform_data = &msm_fb_pdata,
1621 }
1622};
1623
1624#ifdef CONFIG_FB_MSM_MIPI_DSI
1625static int mipi_renesas_set_bl(int level)
1626{
1627 int ret;
1628
1629 ret = pmapp_disp_backlight_set_brightness(level);
1630
1631 if (ret)
1632 pr_err("%s: can't set lcd backlight!\n", __func__);
1633
1634 return ret;
1635}
1636
1637static struct msm_panel_common_pdata mipi_renesas_pdata = {
1638 .pmic_backlight = mipi_renesas_set_bl,
1639};
1640
1641
1642static struct platform_device mipi_dsi_renesas_panel_device = {
1643 .name = "mipi_renesas",
1644 .id = 0,
1645 .dev = {
1646 .platform_data = &mipi_renesas_pdata,
1647 }
1648};
1649#endif
1650
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001651#define SND(desc, num) { .name = #desc, .id = num }
1652static struct snd_endpoint snd_endpoints_list[] = {
1653 SND(HANDSET, 0),
1654 SND(MONO_HEADSET, 2),
1655 SND(HEADSET, 3),
1656 SND(SPEAKER, 6),
1657 SND(TTY_HEADSET, 8),
1658 SND(TTY_VCO, 9),
1659 SND(TTY_HCO, 10),
1660 SND(BT, 12),
1661 SND(IN_S_SADC_OUT_HANDSET, 16),
1662 SND(IN_S_SADC_OUT_SPEAKER_PHONE, 25),
1663 SND(FM_DIGITAL_STEREO_HEADSET, 26),
1664 SND(FM_DIGITAL_SPEAKER_PHONE, 27),
1665 SND(FM_DIGITAL_BT_A2DP_HEADSET, 28),
Shashi Kumar64e07602011-10-11 13:18:57 +05301666 SND(STEREO_HEADSET_AND_SPEAKER, 31),
Sidipotu Ashokab34ca42011-07-22 16:34:20 +05301667 SND(CURRENT, 0x7FFFFFFE),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001668 SND(FM_ANALOG_STEREO_HEADSET, 35),
1669 SND(FM_ANALOG_STEREO_HEADSET_CODEC, 36),
1670};
1671#undef SND
1672
1673static struct msm_snd_endpoints msm_device_snd_endpoints = {
1674 .endpoints = snd_endpoints_list,
1675 .num = sizeof(snd_endpoints_list) / sizeof(struct snd_endpoint)
1676};
1677
1678static struct platform_device msm_device_snd = {
1679 .name = "msm_snd",
1680 .id = -1,
1681 .dev = {
1682 .platform_data = &msm_device_snd_endpoints
1683 },
1684};
1685
1686#define DEC0_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1687 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1688 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1689 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1690 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1691 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1692#define DEC1_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1693 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1694 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1695 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1696 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1697 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1698#define DEC2_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1699 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1700 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1701 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1702 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1703 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1704#define DEC3_FORMAT ((1<<MSM_ADSP_CODEC_MP3)| \
1705 (1<<MSM_ADSP_CODEC_AAC)|(1<<MSM_ADSP_CODEC_WMA)| \
1706 (1<<MSM_ADSP_CODEC_WMAPRO)|(1<<MSM_ADSP_CODEC_AMRWB)| \
1707 (1<<MSM_ADSP_CODEC_AMRNB)|(1<<MSM_ADSP_CODEC_WAV)| \
1708 (1<<MSM_ADSP_CODEC_ADPCM)|(1<<MSM_ADSP_CODEC_YADPCM)| \
1709 (1<<MSM_ADSP_CODEC_EVRC)|(1<<MSM_ADSP_CODEC_QCELP))
1710#define DEC4_FORMAT (1<<MSM_ADSP_CODEC_MIDI)
1711
1712static unsigned int dec_concurrency_table[] = {
1713 /* Audio LP */
1714 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DMA)), 0,
1715 0, 0, 0,
1716
1717 /* Concurrency 1 */
1718 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1719 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1720 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1721 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1722 (DEC4_FORMAT),
1723
1724 /* Concurrency 2 */
1725 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1726 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1727 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1728 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1729 (DEC4_FORMAT),
1730
1731 /* Concurrency 3 */
1732 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1733 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1734 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1735 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1736 (DEC4_FORMAT),
1737
1738 /* Concurrency 4 */
1739 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1740 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1741 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1742 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1743 (DEC4_FORMAT),
1744
1745 /* Concurrency 5 */
1746 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_TUNNEL)|(1<<MSM_ADSP_OP_DM)),
1747 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1748 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1749 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1750 (DEC4_FORMAT),
1751
1752 /* Concurrency 6 */
1753 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1754 0, 0, 0, 0,
1755
1756 /* Concurrency 7 */
1757 (DEC0_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1758 (DEC1_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1759 (DEC2_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1760 (DEC3_FORMAT|(1<<MSM_ADSP_MODE_NONTUNNEL)|(1<<MSM_ADSP_OP_DM)),
1761 (DEC4_FORMAT),
1762};
1763
1764#define DEC_INFO(name, queueid, decid, nr_codec) { .module_name = name, \
1765 .module_queueid = queueid, .module_decid = decid, \
1766 .nr_codec_support = nr_codec}
1767
1768static struct msm_adspdec_info dec_info_list[] = {
1769 DEC_INFO("AUDPLAY0TASK", 13, 0, 11), /* AudPlay0BitStreamCtrlQueue */
1770 DEC_INFO("AUDPLAY1TASK", 14, 1, 11), /* AudPlay1BitStreamCtrlQueue */
1771 DEC_INFO("AUDPLAY2TASK", 15, 2, 11), /* AudPlay2BitStreamCtrlQueue */
1772 DEC_INFO("AUDPLAY3TASK", 16, 3, 11), /* AudPlay3BitStreamCtrlQueue */
1773 DEC_INFO("AUDPLAY4TASK", 17, 4, 1), /* AudPlay4BitStreamCtrlQueue */
1774};
1775
1776static struct msm_adspdec_database msm_device_adspdec_database = {
1777 .num_dec = ARRAY_SIZE(dec_info_list),
1778 .num_concurrency_support = (ARRAY_SIZE(dec_concurrency_table) / \
1779 ARRAY_SIZE(dec_info_list)),
1780 .dec_concurrency_table = dec_concurrency_table,
1781 .dec_info_list = dec_info_list,
1782};
1783
1784static struct platform_device msm_device_adspdec = {
1785 .name = "msm_adspdec",
1786 .id = -1,
1787 .dev = {
1788 .platform_data = &msm_device_adspdec_database
1789 },
1790};
1791
1792static struct android_pmem_platform_data android_pmem_audio_pdata = {
1793 .name = "pmem_audio",
1794 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
1795 .cached = 0,
1796 .memory_type = MEMTYPE_EBI1,
1797};
1798
1799static struct platform_device android_pmem_audio_device = {
1800 .name = "android_pmem",
1801 .id = 2,
1802 .dev = { .platform_data = &android_pmem_audio_pdata },
1803};
1804
1805static struct android_pmem_platform_data android_pmem_pdata = {
1806 .name = "pmem",
1807 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
1808 .cached = 1,
1809 .memory_type = MEMTYPE_EBI1,
1810};
1811static struct platform_device android_pmem_device = {
1812 .name = "android_pmem",
1813 .id = 0,
1814 .dev = { .platform_data = &android_pmem_pdata },
1815};
1816
1817static u32 msm_calculate_batt_capacity(u32 current_voltage);
1818
1819static struct msm_psy_batt_pdata msm_psy_batt_data = {
1820 .voltage_min_design = 2800,
1821 .voltage_max_design = 4300,
1822 .avail_chg_sources = AC_CHG | USB_CHG ,
1823 .batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
1824 .calculate_capacity = &msm_calculate_batt_capacity,
1825};
1826
1827static u32 msm_calculate_batt_capacity(u32 current_voltage)
1828{
1829 u32 low_voltage = msm_psy_batt_data.voltage_min_design;
1830 u32 high_voltage = msm_psy_batt_data.voltage_max_design;
1831
1832 return (current_voltage - low_voltage) * 100
1833 / (high_voltage - low_voltage);
1834}
1835
1836static struct platform_device msm_batt_device = {
1837 .name = "msm-battery",
1838 .id = -1,
1839 .dev.platform_data = &msm_psy_batt_data,
1840};
1841
1842static struct smsc911x_platform_config smsc911x_config = {
1843 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
1844 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
1845 .flags = SMSC911X_USE_16BIT,
1846};
1847
1848static struct resource smsc911x_resources[] = {
1849 [0] = {
1850 .start = 0x90000000,
1851 .end = 0x90007fff,
1852 .flags = IORESOURCE_MEM,
1853 },
1854 [1] = {
1855 .start = MSM_GPIO_TO_INT(48),
1856 .end = MSM_GPIO_TO_INT(48),
1857 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
1858 },
1859};
1860
1861static struct platform_device smsc911x_device = {
1862 .name = "smsc911x",
1863 .id = 0,
1864 .num_resources = ARRAY_SIZE(smsc911x_resources),
1865 .resource = smsc911x_resources,
1866 .dev = {
1867 .platform_data = &smsc911x_config,
1868 },
1869};
1870
1871static struct msm_gpio smsc911x_gpios[] = {
1872 { GPIO_CFG(48, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
1873 "smsc911x_irq" },
1874 { GPIO_CFG(49, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
1875 "eth_fifo_sel" },
1876};
1877
1878#define ETH_FIFO_SEL_GPIO 49
1879static void msm7x27a_cfg_smsc911x(void)
1880{
1881 int res;
1882
1883 res = msm_gpios_request_enable(smsc911x_gpios,
1884 ARRAY_SIZE(smsc911x_gpios));
1885 if (res) {
1886 pr_err("%s: unable to enable gpios for SMSC911x\n", __func__);
1887 return;
1888 }
1889
1890 /* ETH_FIFO_SEL */
1891 res = gpio_direction_output(ETH_FIFO_SEL_GPIO, 0);
1892 if (res) {
1893 pr_err("%s: unable to get direction for gpio %d\n", __func__,
1894 ETH_FIFO_SEL_GPIO);
1895 msm_gpios_disable_free(smsc911x_gpios,
1896 ARRAY_SIZE(smsc911x_gpios));
1897 return;
1898 }
1899 gpio_set_value(ETH_FIFO_SEL_GPIO, 0);
1900}
1901
1902#ifdef CONFIG_MSM_CAMERA
1903static uint32_t camera_off_gpio_table[] = {
1904 GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
1905};
1906
1907static uint32_t camera_on_gpio_table[] = {
1908 GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
1909};
1910
1911#ifdef CONFIG_MSM_CAMERA_FLASH
1912static struct msm_camera_sensor_flash_src msm_flash_src = {
Nishant Pandit474f2252011-07-23 23:17:56 +05301913 .flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
1914 ._fsrc.ext_driver_src.led_en = GPIO_CAM_GP_LED_EN1,
1915 ._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001916};
1917#endif
1918
Justin Paupored98328e2011-08-19 13:48:31 -07001919static struct regulator_bulk_data regs_camera[] = {
1920 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
1921 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
1922 { .supply = "usb2", .min_uV = 1800000, .max_uV = 1800000 },
1923};
1924
1925static void __init msm_camera_vreg_init(void)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001926{
1927 int rc;
1928
Justin Paupored98328e2011-08-19 13:48:31 -07001929 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001930
Justin Paupored98328e2011-08-19 13:48:31 -07001931 if (rc) {
1932 pr_err("%s: could not get regulators: %d\n", __func__, rc);
1933 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001934 }
1935
Justin Paupored98328e2011-08-19 13:48:31 -07001936 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001937
Justin Paupored98328e2011-08-19 13:48:31 -07001938 if (rc) {
1939 pr_err("%s: could not set voltages: %d\n", __func__, rc);
1940 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001941 }
Justin Paupored98328e2011-08-19 13:48:31 -07001942}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001943
Justin Paupored98328e2011-08-19 13:48:31 -07001944static void msm_camera_vreg_config(int vreg_en)
1945{
1946 int rc = vreg_en ?
1947 regulator_bulk_enable(ARRAY_SIZE(regs_camera), regs_camera) :
1948 regulator_bulk_disable(ARRAY_SIZE(regs_camera), regs_camera);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001949
Justin Paupored98328e2011-08-19 13:48:31 -07001950 if (rc)
1951 pr_err("%s: could not %sable regulators: %d\n",
1952 __func__, vreg_en ? "en" : "dis", rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001953}
1954
1955static int config_gpio_table(uint32_t *table, int len)
1956{
1957 int rc = 0, i = 0;
1958
1959 for (i = 0; i < len; i++) {
1960 rc = gpio_tlmm_config(table[i], GPIO_CFG_ENABLE);
1961 if (rc) {
1962 pr_err("%s not able to get gpio\n", __func__);
1963 for (i--; i >= 0; i--)
1964 gpio_tlmm_config(camera_off_gpio_table[i],
1965 GPIO_CFG_ENABLE);
1966 break;
1967 }
1968 }
1969 return rc;
1970}
1971
1972static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data;
1973static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data;
1974static int config_camera_on_gpios_rear(void)
1975{
1976 int rc = 0;
1977
Trilok Soni3d0f6c52011-07-26 16:06:58 +05301978 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001979 msm_camera_vreg_config(1);
1980
1981 rc = config_gpio_table(camera_on_gpio_table,
1982 ARRAY_SIZE(camera_on_gpio_table));
1983 if (rc < 0) {
1984 pr_err("%s: CAMSENSOR gpio table request"
1985 "failed\n", __func__);
1986 return rc;
1987 }
1988
1989 return rc;
1990}
1991
1992static void config_camera_off_gpios_rear(void)
1993{
Trilok Soni3d0f6c52011-07-26 16:06:58 +05301994 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001995 msm_camera_vreg_config(0);
1996
1997 config_gpio_table(camera_off_gpio_table,
1998 ARRAY_SIZE(camera_off_gpio_table));
1999}
2000
2001static int config_camera_on_gpios_front(void)
2002{
2003 int rc = 0;
2004
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302005 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002006 msm_camera_vreg_config(1);
2007
2008 rc = config_gpio_table(camera_on_gpio_table,
2009 ARRAY_SIZE(camera_on_gpio_table));
2010 if (rc < 0) {
2011 pr_err("%s: CAMSENSOR gpio table request"
2012 "failed\n", __func__);
2013 return rc;
2014 }
2015
2016 return rc;
2017}
2018
2019static void config_camera_off_gpios_front(void)
2020{
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302021 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002022 msm_camera_vreg_config(0);
2023
2024 config_gpio_table(camera_off_gpio_table,
2025 ARRAY_SIZE(camera_off_gpio_table));
2026}
2027
2028struct msm_camera_device_platform_data msm_camera_device_data_rear = {
2029 .camera_gpio_on = config_camera_on_gpios_rear,
2030 .camera_gpio_off = config_camera_off_gpios_rear,
2031 .ioext.csiphy = 0xA1000000,
2032 .ioext.csisz = 0x00100000,
2033 .ioext.csiirq = INT_CSI_IRQ_1,
2034 .ioclk.mclk_clk_rate = 24000000,
2035 .ioclk.vfe_clk_rate = 192000000,
2036 .ioext.appphy = MSM_CLK_CTL_PHYS,
2037 .ioext.appsz = MSM_CLK_CTL_SIZE,
2038};
2039
2040struct msm_camera_device_platform_data msm_camera_device_data_front = {
2041 .camera_gpio_on = config_camera_on_gpios_front,
2042 .camera_gpio_off = config_camera_off_gpios_front,
2043 .ioext.csiphy = 0xA0F00000,
2044 .ioext.csisz = 0x00100000,
2045 .ioext.csiirq = INT_CSI_IRQ_0,
2046 .ioclk.mclk_clk_rate = 24000000,
2047 .ioclk.vfe_clk_rate = 192000000,
2048 .ioext.appphy = MSM_CLK_CTL_PHYS,
2049 .ioext.appsz = MSM_CLK_CTL_SIZE,
2050};
2051
2052#ifdef CONFIG_S5K4E1
2053static struct msm_camera_sensor_platform_info s5k4e1_sensor_7627a_info = {
2054 .mount_angle = 90
2055};
2056
2057static struct msm_camera_sensor_flash_data flash_s5k4e1 = {
2058 .flash_type = MSM_CAMERA_FLASH_LED,
2059 .flash_src = &msm_flash_src
2060};
2061
2062static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
2063 .sensor_name = "s5k4e1",
2064 .sensor_reset_enable = 1,
2065 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N,
2066 .sensor_pwd = 85,
2067 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
2068 .vcm_enable = 1,
2069 .pdata = &msm_camera_device_data_rear,
2070 .flash_data = &flash_s5k4e1,
2071 .sensor_platform_info = &s5k4e1_sensor_7627a_info,
2072 .csi_if = 1
2073};
2074
2075static struct platform_device msm_camera_sensor_s5k4e1 = {
2076 .name = "msm_camera_s5k4e1",
2077 .dev = {
2078 .platform_data = &msm_camera_sensor_s5k4e1_data,
2079 },
2080};
2081#endif
2082
2083#ifdef CONFIG_IMX072
2084static struct msm_camera_sensor_platform_info imx072_sensor_7627a_info = {
2085 .mount_angle = 90
2086};
2087
2088static struct msm_camera_sensor_flash_data flash_imx072 = {
2089 .flash_type = MSM_CAMERA_FLASH_LED,
2090 .flash_src = &msm_flash_src
2091};
2092
2093static struct msm_camera_sensor_info msm_camera_sensor_imx072_data = {
2094 .sensor_name = "imx072",
2095 .sensor_reset_enable = 1,
2096 .sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N, /* TODO 106,*/
2097 .sensor_pwd = 85,
2098 .vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
2099 .vcm_enable = 1,
2100 .pdata = &msm_camera_device_data_rear,
2101 .flash_data = &flash_imx072,
2102 .sensor_platform_info = &imx072_sensor_7627a_info,
2103 .csi_if = 1
2104};
2105
2106static struct platform_device msm_camera_sensor_imx072 = {
2107 .name = "msm_camera_imx072",
2108 .dev = {
2109 .platform_data = &msm_camera_sensor_imx072_data,
2110 },
2111};
2112#endif
2113
2114#ifdef CONFIG_WEBCAM_OV9726
2115static struct msm_camera_sensor_platform_info ov9726_sensor_7627a_info = {
2116 .mount_angle = 90
2117};
2118
2119static struct msm_camera_sensor_flash_data flash_ov9726 = {
2120 .flash_type = MSM_CAMERA_FLASH_NONE,
2121 .flash_src = &msm_flash_src
2122};
2123
2124static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
2125 .sensor_name = "ov9726",
2126 .sensor_reset_enable = 0,
2127 .sensor_reset = GPIO_CAM_GP_CAM1MP_XCLR,
2128 .sensor_pwd = 85,
2129 .vcm_pwd = 1,
2130 .vcm_enable = 0,
2131 .pdata = &msm_camera_device_data_front,
2132 .flash_data = &flash_ov9726,
2133 .sensor_platform_info = &ov9726_sensor_7627a_info,
2134 .csi_if = 1
2135};
2136
2137static struct platform_device msm_camera_sensor_ov9726 = {
2138 .name = "msm_camera_ov9726",
2139 .dev = {
2140 .platform_data = &msm_camera_sensor_ov9726_data,
2141 },
2142};
Justin Paupored98328e2011-08-19 13:48:31 -07002143#else
2144static inline void msm_camera_vreg_init(void) { }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002145#endif
2146
2147#ifdef CONFIG_MT9E013
2148static struct msm_camera_sensor_platform_info mt9e013_sensor_7627a_info = {
2149 .mount_angle = 90
2150};
2151
2152static struct msm_camera_sensor_flash_data flash_mt9e013 = {
2153 .flash_type = MSM_CAMERA_FLASH_LED,
2154 .flash_src = &msm_flash_src
2155};
2156
2157static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
2158 .sensor_name = "mt9e013",
2159 .sensor_reset = 0,
2160 .sensor_reset_enable = 1,
2161 .sensor_pwd = 85,
2162 .vcm_pwd = 1,
2163 .vcm_enable = 0,
2164 .pdata = &msm_camera_device_data_rear,
2165 .flash_data = &flash_mt9e013,
2166 .sensor_platform_info = &mt9e013_sensor_7627a_info,
2167 .csi_if = 1
2168};
2169
2170static struct platform_device msm_camera_sensor_mt9e013 = {
2171 .name = "msm_camera_mt9e013",
2172 .dev = {
2173 .platform_data = &msm_camera_sensor_mt9e013_data,
2174 },
2175};
2176#endif
2177
2178static struct i2c_board_info i2c_camera_devices[] = {
2179 #ifdef CONFIG_S5K4E1
2180 {
2181 I2C_BOARD_INFO("s5k4e1", 0x36),
2182 },
2183 {
2184 I2C_BOARD_INFO("s5k4e1_af", 0x8c >> 1),
2185 },
2186 #endif
2187 #ifdef CONFIG_WEBCAM_OV9726
2188 {
2189 I2C_BOARD_INFO("ov9726", 0x10),
2190 },
2191 #endif
2192 #ifdef CONFIG_IMX072
2193 {
2194 I2C_BOARD_INFO("imx072", 0x34),
2195 },
2196 #endif
2197 #ifdef CONFIG_MT9E013
2198 {
2199 I2C_BOARD_INFO("mt9e013", 0x6C >> 2),
2200 },
2201 #endif
2202 {
Nishant Pandit474f2252011-07-23 23:17:56 +05302203 I2C_BOARD_INFO("sc628a", 0x6E),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002204 },
2205};
2206#endif
2207#if defined(CONFIG_SERIAL_MSM_HSL_CONSOLE) \
2208 && defined(CONFIG_MSM_SHARED_GPIO_FOR_UART2DM)
2209static struct msm_gpio uart2dm_gpios[] = {
2210 {GPIO_CFG(19, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2211 "uart2dm_rfr_n" },
2212 {GPIO_CFG(20, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2213 "uart2dm_cts_n" },
2214 {GPIO_CFG(21, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2215 "uart2dm_rx" },
2216 {GPIO_CFG(108, 2, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2217 "uart2dm_tx" },
2218};
2219
2220static void msm7x27a_cfg_uart2dm_serial(void)
2221{
2222 int ret;
2223 ret = msm_gpios_request_enable(uart2dm_gpios,
2224 ARRAY_SIZE(uart2dm_gpios));
2225 if (ret)
2226 pr_err("%s: unable to enable gpios for uart2dm\n", __func__);
2227}
2228#else
2229static void msm7x27a_cfg_uart2dm_serial(void) { }
2230#endif
2231
2232static struct platform_device *rumi_sim_devices[] __initdata = {
2233 &msm_device_dmov,
2234 &msm_device_smd,
2235 &smc91x_device,
2236 &msm_device_uart1,
2237 &msm_device_nand,
2238 &msm_device_uart_dm1,
2239 &msm_gsbi0_qup_i2c_device,
2240 &msm_gsbi1_qup_i2c_device,
2241};
2242
2243static struct platform_device *surf_ffa_devices[] __initdata = {
2244 &msm_device_dmov,
2245 &msm_device_smd,
2246 &msm_device_uart1,
2247 &msm_device_uart_dm1,
2248 &msm_device_uart_dm2,
2249 &msm_device_nand,
2250 &msm_gsbi0_qup_i2c_device,
2251 &msm_gsbi1_qup_i2c_device,
2252 &msm_device_otg,
2253 &msm_device_gadget_peripheral,
2254 &android_usb_device,
2255 &android_pmem_device,
2256 &android_pmem_adsp_device,
2257 &android_pmem_audio_device,
2258 &msm_device_snd,
2259 &msm_device_adspdec,
2260 &msm_fb_device,
2261 &lcdc_toshiba_panel_device,
2262 &msm_batt_device,
2263 &smsc911x_device,
2264#ifdef CONFIG_S5K4E1
2265 &msm_camera_sensor_s5k4e1,
2266#endif
2267#ifdef CONFIG_IMX072
2268 &msm_camera_sensor_imx072,
2269#endif
2270#ifdef CONFIG_WEBCAM_OV9726
2271 &msm_camera_sensor_ov9726,
2272#endif
2273#ifdef CONFIG_MT9E013
2274 &msm_camera_sensor_mt9e013,
2275#endif
2276#ifdef CONFIG_FB_MSM_MIPI_DSI
2277 &mipi_dsi_renesas_panel_device,
2278#endif
2279 &msm_kgsl_3d0,
2280#ifdef CONFIG_BT
2281 &msm_bt_power_device,
2282#endif
Manish Dewangan3a260992011-06-24 18:01:34 +05302283 &asoc_msm_pcm,
2284 &asoc_msm_dai0,
2285 &asoc_msm_dai1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002286};
2287
2288static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
2289static int __init pmem_kernel_ebi1_size_setup(char *p)
2290{
2291 pmem_kernel_ebi1_size = memparse(p, NULL);
2292 return 0;
2293}
2294early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
2295
2296static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
2297static int __init pmem_audio_size_setup(char *p)
2298{
2299 pmem_audio_size = memparse(p, NULL);
2300 return 0;
2301}
2302early_param("pmem_audio_size", pmem_audio_size_setup);
2303
2304static void __init msm_msm7x2x_allocate_memory_regions(void)
2305{
2306 void *addr;
2307 unsigned long size;
2308
Jeevan Shriramf40764e2011-10-31 23:28:26 +05302309 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
2310 fb_size = MSM7x25A_MSM_FB_SIZE;
2311 else
2312 fb_size = MSM_FB_SIZE;
2313
2314 size = fb_size;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002315 addr = alloc_bootmem_align(size, 0x1000);
2316 msm_fb_resources[0].start = __pa(addr);
2317 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
2318 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
2319 size, addr, __pa(addr));
2320}
2321
2322static struct memtype_reserve msm7x27a_reserve_table[] __initdata = {
2323 [MEMTYPE_SMI] = {
2324 },
2325 [MEMTYPE_EBI0] = {
2326 .flags = MEMTYPE_FLAGS_1M_ALIGN,
2327 },
2328 [MEMTYPE_EBI1] = {
2329 .flags = MEMTYPE_FLAGS_1M_ALIGN,
2330 },
2331};
2332
2333static void __init size_pmem_devices(void)
2334{
Jeevan Shriramf40764e2011-10-31 23:28:26 +05302335
2336 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
2337 pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
2338 pmem_adsp_size = MSM7x25A_MSM_PMEM_ADSP_SIZE;
2339 } else {
2340 pmem_mdp_size = MSM_PMEM_MDP_SIZE;
2341 pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
2342 }
2343
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002344#ifdef CONFIG_ANDROID_PMEM
2345 android_pmem_adsp_pdata.size = pmem_adsp_size;
2346 android_pmem_pdata.size = pmem_mdp_size;
2347 android_pmem_audio_pdata.size = pmem_audio_size;
2348#endif
2349}
2350
2351static void __init reserve_memory_for(struct android_pmem_platform_data *p)
2352{
2353 msm7x27a_reserve_table[p->memory_type].size += p->size;
2354}
2355
2356static void __init reserve_pmem_memory(void)
2357{
2358#ifdef CONFIG_ANDROID_PMEM
2359 reserve_memory_for(&android_pmem_adsp_pdata);
2360 reserve_memory_for(&android_pmem_pdata);
2361 reserve_memory_for(&android_pmem_audio_pdata);
2362 msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
2363#endif
2364}
2365
2366static void __init msm7x27a_calculate_reserve_sizes(void)
2367{
2368 size_pmem_devices();
2369 reserve_pmem_memory();
2370}
2371
2372static int msm7x27a_paddr_to_memtype(unsigned int paddr)
2373{
2374 return MEMTYPE_EBI1;
2375}
2376
2377static struct reserve_info msm7x27a_reserve_info __initdata = {
2378 .memtype_reserve_table = msm7x27a_reserve_table,
2379 .calculate_reserve_sizes = msm7x27a_calculate_reserve_sizes,
2380 .paddr_to_memtype = msm7x27a_paddr_to_memtype,
2381};
2382
2383static void __init msm7x27a_reserve(void)
2384{
2385 reserve_info = &msm7x27a_reserve_info;
2386 msm_reserve();
2387}
2388
2389static void __init msm_device_i2c_init(void)
2390{
2391 msm_gsbi0_qup_i2c_device.dev.platform_data = &msm_gsbi0_qup_i2c_pdata;
2392 msm_gsbi1_qup_i2c_device.dev.platform_data = &msm_gsbi1_qup_i2c_pdata;
2393}
2394
2395static struct msm_panel_common_pdata mdp_pdata = {
2396 .gpio = 97,
2397 .mdp_rev = MDP_REV_303,
2398};
2399
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302400
2401#ifdef CONFIG_FB_MSM
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002402#define GPIO_LCDC_BRDG_PD 128
2403#define GPIO_LCDC_BRDG_RESET_N 129
2404
2405#define LCDC_RESET_PHYS 0x90008014
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302406
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002407static void __iomem *lcdc_reset_ptr;
2408
2409static unsigned mipi_dsi_gpio[] = {
2410 GPIO_CFG(GPIO_LCDC_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2411 GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
2412 GPIO_CFG(GPIO_LCDC_BRDG_PD, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2413 GPIO_CFG_2MA), /* LCDC_BRDG_RESET_N */
2414};
2415
2416enum {
2417 DSI_SINGLE_LANE = 1,
2418 DSI_TWO_LANES,
2419};
2420
2421static int msm_fb_get_lane_config(void)
2422{
2423 int rc = DSI_TWO_LANES;
2424
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302425 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002426 rc = DSI_SINGLE_LANE;
2427 pr_info("DSI Single Lane\n");
2428 } else {
2429 pr_info("DSI Two Lanes\n");
2430 }
2431 return rc;
2432}
2433
2434static int msm_fb_dsi_client_reset(void)
2435{
2436 int rc = 0;
2437
2438 rc = gpio_request(GPIO_LCDC_BRDG_RESET_N, "lcdc_brdg_reset_n");
2439 if (rc < 0) {
2440 pr_err("failed to request lcd brdg reset_n\n");
2441 return rc;
2442 }
2443
2444 rc = gpio_request(GPIO_LCDC_BRDG_PD, "lcdc_brdg_pd");
2445 if (rc < 0) {
2446 pr_err("failed to request lcd brdg pd\n");
2447 return rc;
2448 }
2449
2450 rc = gpio_tlmm_config(mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
2451 if (rc) {
2452 pr_err("Failed to enable LCDC Bridge reset enable\n");
2453 goto gpio_error;
2454 }
2455
2456 rc = gpio_tlmm_config(mipi_dsi_gpio[1], GPIO_CFG_ENABLE);
2457 if (rc) {
2458 pr_err("Failed to enable LCDC Bridge pd enable\n");
2459 goto gpio_error2;
2460 }
2461
2462 rc = gpio_direction_output(GPIO_LCDC_BRDG_RESET_N, 1);
2463 rc |= gpio_direction_output(GPIO_LCDC_BRDG_PD, 1);
2464 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
2465
2466 if (!rc) {
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302467 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002468 lcdc_reset_ptr = ioremap_nocache(LCDC_RESET_PHYS,
2469 sizeof(uint32_t));
2470
2471 if (!lcdc_reset_ptr)
2472 return 0;
2473 }
2474 return rc;
2475 } else {
2476 goto gpio_error;
2477 }
2478
2479gpio_error2:
2480 pr_err("Failed GPIO bridge pd\n");
2481 gpio_free(GPIO_LCDC_BRDG_PD);
2482
2483gpio_error:
2484 pr_err("Failed GPIO bridge reset\n");
2485 gpio_free(GPIO_LCDC_BRDG_RESET_N);
2486 return rc;
2487}
2488
Justin Paupored98328e2011-08-19 13:48:31 -07002489static struct regulator_bulk_data regs_dsi[] = {
2490 { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
2491 { .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002492};
2493
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002494static int dsi_gpio_initialized;
2495
2496static int mipi_dsi_panel_power(int on)
2497{
Justin Paupored98328e2011-08-19 13:48:31 -07002498 int rc = 0;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002499 uint32_t lcdc_reset_cfg;
2500
2501 /* I2C-controlled GPIO Expander -init of the GPIOs very late */
Justin Paupored98328e2011-08-19 13:48:31 -07002502 if (unlikely(!dsi_gpio_initialized)) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002503 pmapp_disp_backlight_init();
2504
2505 rc = gpio_request(GPIO_DISPLAY_PWR_EN, "gpio_disp_pwr");
2506 if (rc < 0) {
2507 pr_err("failed to request gpio_disp_pwr\n");
2508 return rc;
2509 }
2510
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302511 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002512 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, 1);
2513 if (rc < 0) {
2514 pr_err("failed to enable display pwr\n");
2515 goto fail_gpio1;
2516 }
2517
2518 rc = gpio_request(GPIO_BACKLIGHT_EN, "gpio_bkl_en");
2519 if (rc < 0) {
2520 pr_err("failed to request gpio_bkl_en\n");
2521 goto fail_gpio1;
2522 }
2523
2524 rc = gpio_direction_output(GPIO_BACKLIGHT_EN, 1);
2525 if (rc < 0) {
2526 pr_err("failed to enable backlight\n");
2527 goto fail_gpio2;
2528 }
2529 }
2530
Justin Paupored98328e2011-08-19 13:48:31 -07002531 rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_dsi), regs_dsi);
2532 if (rc) {
2533 pr_err("%s: could not get regulators: %d\n",
2534 __func__, rc);
2535 goto fail_gpio2;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002536 }
Justin Paupored98328e2011-08-19 13:48:31 -07002537
2538 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_dsi), regs_dsi);
2539 if (rc) {
2540 pr_err("%s: could not set voltages: %d\n",
2541 __func__, rc);
2542 goto fail_vreg;
2543 }
2544
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002545 dsi_gpio_initialized = 1;
2546 }
2547
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302548 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf()) {
Justin Paupored98328e2011-08-19 13:48:31 -07002549 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, on);
2550 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, on);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302551 } else if (machine_is_msm7x27a_ffa() ||
2552 machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002553 if (on) {
Justin Paupored98328e2011-08-19 13:48:31 -07002554 /* This line drives an active low pin on FFA */
2555 rc = gpio_direction_output(GPIO_DISPLAY_PWR_EN, !on);
2556 if (rc < 0)
2557 pr_err("failed to set direction for "
2558 "display pwr\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002559 } else {
Justin Paupored98328e2011-08-19 13:48:31 -07002560 gpio_set_value_cansleep(GPIO_DISPLAY_PWR_EN, !on);
2561 rc = gpio_direction_input(GPIO_DISPLAY_PWR_EN);
2562 if (rc < 0)
2563 pr_err("failed to set direction for "
2564 "display pwr\n");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002565 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002566 }
2567
Justin Paupored98328e2011-08-19 13:48:31 -07002568 if (on) {
2569 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 0);
2570
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302571 if (machine_is_msm7x27a_surf() ||
2572 machine_is_msm7625a_surf()) {
Justin Paupored98328e2011-08-19 13:48:31 -07002573 lcdc_reset_cfg = readl_relaxed(lcdc_reset_ptr);
2574 rmb();
2575 lcdc_reset_cfg &= ~1;
2576
2577 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
2578 msleep(20);
2579 wmb();
2580 lcdc_reset_cfg |= 1;
2581 writel_relaxed(lcdc_reset_cfg, lcdc_reset_ptr);
2582 } else {
2583 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 0);
2584 msleep(20);
2585 gpio_set_value_cansleep(GPIO_LCDC_BRDG_RESET_N, 1);
2586 }
2587
2588 if (pmapp_disp_backlight_set_brightness(100))
2589 pr_err("backlight set brightness failed\n");
2590 } else {
2591 gpio_set_value_cansleep(GPIO_LCDC_BRDG_PD, 1);
2592
2593 if (pmapp_disp_backlight_set_brightness(0))
2594 pr_err("backlight set brightness failed\n");
2595 }
2596
2597 rc = on ? regulator_bulk_enable(ARRAY_SIZE(regs_dsi), regs_dsi) :
2598 regulator_bulk_disable(ARRAY_SIZE(regs_dsi), regs_dsi);
2599
2600 if (rc)
2601 pr_err("%s: could not %sable regulators: %d\n",
2602 __func__, on ? "en" : "dis", rc);
2603
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002604 return rc;
2605
Justin Paupored98328e2011-08-19 13:48:31 -07002606fail_vreg:
2607 regulator_bulk_free(ARRAY_SIZE(regs_dsi), regs_dsi);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002608fail_gpio2:
2609 gpio_free(GPIO_BACKLIGHT_EN);
2610fail_gpio1:
2611 gpio_free(GPIO_DISPLAY_PWR_EN);
2612 dsi_gpio_initialized = 0;
2613 return rc;
2614}
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302615#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002616
2617#define MDP_303_VSYNC_GPIO 97
2618
2619#ifdef CONFIG_FB_MSM_MDP303
2620static struct mipi_dsi_platform_data mipi_dsi_pdata = {
2621 .vsync_gpio = MDP_303_VSYNC_GPIO,
2622 .dsi_power_save = mipi_dsi_panel_power,
2623 .dsi_client_reset = msm_fb_dsi_client_reset,
2624 .get_lane_config = msm_fb_get_lane_config,
2625};
2626#endif
2627
2628static void __init msm_fb_add_devices(void)
2629{
2630 msm_fb_register_device("mdp", &mdp_pdata);
2631 msm_fb_register_device("lcdc", &lcdc_pdata);
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302632#ifdef CONFIG_FB_MSM_MDP303
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002633 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
Pankaj Kumarffdaec82011-09-26 12:24:45 +05302634#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002635}
2636
2637#define MSM_EBI2_PHYS 0xa0d00000
2638#define MSM_EBI2_XMEM_CS2_CFG1 0xa0d10030
2639
2640static void __init msm7x27a_init_ebi2(void)
2641{
2642 uint32_t ebi2_cfg;
2643 void __iomem *ebi2_cfg_ptr;
2644
2645 ebi2_cfg_ptr = ioremap_nocache(MSM_EBI2_PHYS, sizeof(uint32_t));
2646 if (!ebi2_cfg_ptr)
2647 return;
2648
2649 ebi2_cfg = readl(ebi2_cfg_ptr);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302650 if (machine_is_msm7x27a_rumi3() || machine_is_msm7x27a_surf() ||
2651 machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002652 ebi2_cfg |= (1 << 4); /* CS2 */
2653
2654 writel(ebi2_cfg, ebi2_cfg_ptr);
2655 iounmap(ebi2_cfg_ptr);
2656
2657 /* Enable A/D MUX[bit 31] from EBI2_XMEM_CS2_CFG1 */
2658 ebi2_cfg_ptr = ioremap_nocache(MSM_EBI2_XMEM_CS2_CFG1,
2659 sizeof(uint32_t));
2660 if (!ebi2_cfg_ptr)
2661 return;
2662
2663 ebi2_cfg = readl(ebi2_cfg_ptr);
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302664 if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002665 ebi2_cfg |= (1 << 31);
2666
2667 writel(ebi2_cfg, ebi2_cfg_ptr);
2668 iounmap(ebi2_cfg_ptr);
2669}
2670
2671#define ATMEL_TS_I2C_NAME "maXTouch"
Justin Paupored98328e2011-08-19 13:48:31 -07002672
2673static struct regulator_bulk_data regs_atmel[] = {
2674 { .supply = "ldo2", .min_uV = 2850000, .max_uV = 2850000 },
2675 { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
2676};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002677
2678#define ATMEL_TS_GPIO_IRQ 82
2679
2680static int atmel_ts_power_on(bool on)
2681{
Justin Paupored98328e2011-08-19 13:48:31 -07002682 int rc = on ?
2683 regulator_bulk_enable(ARRAY_SIZE(regs_atmel), regs_atmel) :
2684 regulator_bulk_disable(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002685
Justin Paupored98328e2011-08-19 13:48:31 -07002686 if (rc)
2687 pr_err("%s: could not %sable regulators: %d\n",
2688 __func__, on ? "en" : "dis", rc);
2689 else
2690 msleep(50);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002691
Justin Paupored98328e2011-08-19 13:48:31 -07002692 return rc;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002693}
2694
2695static int atmel_ts_platform_init(struct i2c_client *client)
2696{
2697 int rc;
Justin Paupored98328e2011-08-19 13:48:31 -07002698 struct device *dev = &client->dev;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002699
Justin Paupored98328e2011-08-19 13:48:31 -07002700 rc = regulator_bulk_get(dev, ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002701 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002702 dev_err(dev, "%s: could not get regulators: %d\n",
2703 __func__, rc);
2704 goto out;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002705 }
2706
Justin Paupored98328e2011-08-19 13:48:31 -07002707 rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002708 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002709 dev_err(dev, "%s: could not set voltages: %d\n",
2710 __func__, rc);
2711 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002712 }
2713
2714 rc = gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
2715 GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
2716 GPIO_CFG_8MA), GPIO_CFG_ENABLE);
2717 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002718 dev_err(dev, "%s: gpio_tlmm_config for %d failed\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002719 __func__, ATMEL_TS_GPIO_IRQ);
Justin Paupored98328e2011-08-19 13:48:31 -07002720 goto reg_free;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002721 }
2722
2723 /* configure touchscreen interrupt gpio */
2724 rc = gpio_request(ATMEL_TS_GPIO_IRQ, "atmel_maxtouch_gpio");
2725 if (rc) {
Justin Paupored98328e2011-08-19 13:48:31 -07002726 dev_err(dev, "%s: unable to request gpio %d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002727 __func__, ATMEL_TS_GPIO_IRQ);
2728 goto ts_gpio_tlmm_unconfig;
2729 }
2730
2731 rc = gpio_direction_input(ATMEL_TS_GPIO_IRQ);
2732 if (rc < 0) {
Justin Paupored98328e2011-08-19 13:48:31 -07002733 dev_err(dev, "%s: unable to set the direction of gpio %d\n",
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002734 __func__, ATMEL_TS_GPIO_IRQ);
2735 goto free_ts_gpio;
2736 }
2737 return 0;
2738
2739free_ts_gpio:
2740 gpio_free(ATMEL_TS_GPIO_IRQ);
2741ts_gpio_tlmm_unconfig:
2742 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
2743 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
2744 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
Justin Paupored98328e2011-08-19 13:48:31 -07002745reg_free:
2746 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
2747out:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002748 return rc;
2749}
2750
2751static int atmel_ts_platform_exit(struct i2c_client *client)
2752{
2753 gpio_free(ATMEL_TS_GPIO_IRQ);
2754 gpio_tlmm_config(GPIO_CFG(ATMEL_TS_GPIO_IRQ, 0,
2755 GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,
2756 GPIO_CFG_2MA), GPIO_CFG_DISABLE);
Justin Paupored98328e2011-08-19 13:48:31 -07002757 regulator_bulk_free(ARRAY_SIZE(regs_atmel), regs_atmel);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002758 return 0;
2759}
2760
2761static u8 atmel_ts_read_chg(void)
2762{
2763 return gpio_get_value(ATMEL_TS_GPIO_IRQ);
2764}
2765
2766static u8 atmel_ts_valid_interrupt(void)
2767{
2768 return !atmel_ts_read_chg();
2769}
2770
2771#define ATMEL_X_OFFSET 13
2772#define ATMEL_Y_OFFSET 0
2773
Mohan Pallaka4e9a94e2011-11-23 16:34:21 +05302774static struct maxtouch_platform_data atmel_ts_pdata = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002775 .numtouch = 4,
2776 .init_platform_hw = atmel_ts_platform_init,
2777 .exit_platform_hw = atmel_ts_platform_exit,
2778 .power_on = atmel_ts_power_on,
2779 .display_res_x = 480,
2780 .display_res_y = 864,
2781 .min_x = ATMEL_X_OFFSET,
2782 .max_x = (505 - ATMEL_X_OFFSET),
2783 .min_y = ATMEL_Y_OFFSET,
2784 .max_y = (863 - ATMEL_Y_OFFSET),
2785 .valid_interrupt = atmel_ts_valid_interrupt,
2786 .read_chg = atmel_ts_read_chg,
2787};
2788
2789static struct i2c_board_info atmel_ts_i2c_info[] __initdata = {
2790 {
2791 I2C_BOARD_INFO(ATMEL_TS_I2C_NAME, 0x4a),
2792 .platform_data = &atmel_ts_pdata,
2793 .irq = MSM_GPIO_TO_INT(ATMEL_TS_GPIO_IRQ),
2794 },
2795};
2796
2797#define KP_INDEX(row, col) ((row)*ARRAY_SIZE(kp_col_gpios) + (col))
2798
2799static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
2800static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
2801
2802static const unsigned short keymap[ARRAY_SIZE(kp_col_gpios) *
2803 ARRAY_SIZE(kp_row_gpios)] = {
2804 [KP_INDEX(0, 0)] = KEY_7,
2805 [KP_INDEX(0, 1)] = KEY_DOWN,
2806 [KP_INDEX(0, 2)] = KEY_UP,
2807 [KP_INDEX(0, 3)] = KEY_RIGHT,
2808 [KP_INDEX(0, 4)] = KEY_ENTER,
2809
2810 [KP_INDEX(1, 0)] = KEY_LEFT,
2811 [KP_INDEX(1, 1)] = KEY_SEND,
2812 [KP_INDEX(1, 2)] = KEY_1,
2813 [KP_INDEX(1, 3)] = KEY_4,
2814 [KP_INDEX(1, 4)] = KEY_CLEAR,
2815
2816 [KP_INDEX(2, 0)] = KEY_6,
2817 [KP_INDEX(2, 1)] = KEY_5,
2818 [KP_INDEX(2, 2)] = KEY_8,
2819 [KP_INDEX(2, 3)] = KEY_3,
2820 [KP_INDEX(2, 4)] = KEY_NUMERIC_STAR,
2821
2822 [KP_INDEX(3, 0)] = KEY_9,
2823 [KP_INDEX(3, 1)] = KEY_NUMERIC_POUND,
2824 [KP_INDEX(3, 2)] = KEY_0,
2825 [KP_INDEX(3, 3)] = KEY_2,
2826 [KP_INDEX(3, 4)] = KEY_SLEEP,
2827
2828 [KP_INDEX(4, 0)] = KEY_BACK,
2829 [KP_INDEX(4, 1)] = KEY_HOME,
2830 [KP_INDEX(4, 2)] = KEY_MENU,
2831 [KP_INDEX(4, 3)] = KEY_VOLUMEUP,
2832 [KP_INDEX(4, 4)] = KEY_VOLUMEDOWN,
2833};
2834
2835/* SURF keypad platform device information */
2836static struct gpio_event_matrix_info kp_matrix_info = {
2837 .info.func = gpio_event_matrix_func,
2838 .keymap = keymap,
2839 .output_gpios = kp_row_gpios,
2840 .input_gpios = kp_col_gpios,
2841 .noutputs = ARRAY_SIZE(kp_row_gpios),
2842 .ninputs = ARRAY_SIZE(kp_col_gpios),
2843 .settle_time.tv_nsec = 40 * NSEC_PER_USEC,
2844 .poll_time.tv_nsec = 20 * NSEC_PER_MSEC,
2845 .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
2846 GPIOKPF_PRINT_UNMAPPED_KEYS,
2847};
2848
2849static struct gpio_event_info *kp_info[] = {
2850 &kp_matrix_info.info
2851};
2852
2853static struct gpio_event_platform_data kp_pdata = {
2854 .name = "7x27a_kp",
2855 .info = kp_info,
2856 .info_count = ARRAY_SIZE(kp_info)
2857};
2858
2859static struct platform_device kp_pdev = {
2860 .name = GPIO_EVENT_DEV_NAME,
2861 .id = -1,
2862 .dev = {
2863 .platform_data = &kp_pdata,
2864 },
2865};
2866
2867static struct msm_handset_platform_data hs_platform_data = {
2868 .hs_name = "7k_handset",
2869 .pwr_key_delay_ms = 500, /* 0 will disable end key */
2870};
2871
2872static struct platform_device hs_pdev = {
2873 .name = "msm-handset",
2874 .id = -1,
2875 .dev = {
2876 .platform_data = &hs_platform_data,
2877 },
2878};
2879
Justin Pauporeb3a33b72011-08-23 15:30:32 -07002880static struct platform_device msm_proccomm_regulator_dev = {
2881 .name = PROCCOMM_REGULATOR_DEV_NAME,
2882 .id = -1,
2883 .dev = {
2884 .platform_data = &msm7x27a_proccomm_regulator_data
2885 }
2886};
2887
Trilok Soni16f61af2011-07-26 16:06:58 +05302888static void __init msm7627a_rumi3_init(void)
2889{
2890 msm7x27a_init_ebi2();
2891 platform_add_devices(rumi_sim_devices,
2892 ARRAY_SIZE(rumi_sim_devices));
2893}
2894
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002895#define LED_GPIO_PDM 96
2896#define UART1DM_RX_GPIO 45
Santosh Sajjanb479f0f2011-08-18 21:00:44 +05302897
2898#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
2899static int __init msm7x27a_init_ar6000pm(void)
2900{
2901 return platform_device_register(&msm_wlan_ar6000_pm_device);
2902}
2903#else
2904static int __init msm7x27a_init_ar6000pm(void) { return 0; }
2905#endif
2906
Justin Pauporeb3a33b72011-08-23 15:30:32 -07002907static void __init msm7x27a_init_regulators(void)
2908{
2909 int rc = platform_device_register(&msm_proccomm_regulator_dev);
2910 if (rc)
2911 pr_err("%s: could not register regulator device: %d\n",
2912 __func__, rc);
2913}
2914
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002915static void __init msm7x2x_init(void)
2916{
Trilok Sonia416c492011-07-22 20:20:23 +05302917 msm7x2x_misc_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002918
Justin Pauporeb3a33b72011-08-23 15:30:32 -07002919 /* Initialize regulators first so that other devices can use them */
2920 msm7x27a_init_regulators();
2921
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002922 /* Common functions for SURF/FFA/RUMI3 */
2923 msm_device_i2c_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002924 msm7x27a_init_ebi2();
2925 msm7x27a_cfg_uart2dm_serial();
2926#ifdef CONFIG_SERIAL_MSM_HS
2927 msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(UART1DM_RX_GPIO);
2928 msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
2929#endif
2930
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002931#ifdef CONFIG_USB_MSM_OTG_72K
Trilok Soni16f61af2011-07-26 16:06:58 +05302932 msm_otg_pdata.swfi_latency =
2933 msm7x27a_pm_data
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002934 [MSM_PM_SLEEP_MODE_RAMP_DOWN_AND_WAIT_FOR_INTERRUPT].latency;
Trilok Soni16f61af2011-07-26 16:06:58 +05302935 msm_device_otg.dev.platform_data = &msm_otg_pdata;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002936#endif
Trilok Soni16f61af2011-07-26 16:06:58 +05302937 msm_device_gadget_peripheral.dev.platform_data =
2938 &msm_gadget_pdata;
2939 msm7x27a_cfg_smsc911x();
2940 platform_add_devices(msm_footswitch_devices,
2941 msm_num_footswitch_devices);
2942 platform_add_devices(surf_ffa_devices,
2943 ARRAY_SIZE(surf_ffa_devices));
Sujith Reddy Thummaad7c9a82011-09-30 20:54:38 +05302944 /* Ensure ar6000pm device is registered before MMC/SDC */
2945 msm7x27a_init_ar6000pm();
2946#ifdef CONFIG_MMC_MSM
Chintan Pandyacf467fc2011-12-01 17:11:11 +05302947 msm7627a_init_mmc();
Sujith Reddy Thummaad7c9a82011-09-30 20:54:38 +05302948#endif
Trilok Soni16f61af2011-07-26 16:06:58 +05302949 msm_fb_add_devices();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002950#ifdef CONFIG_USB_EHCI_MSM_72K
Trilok Soni16f61af2011-07-26 16:06:58 +05302951 msm7x2x_init_host();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002952#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002953
2954 msm_pm_set_platform_data(msm7x27a_pm_data,
2955 ARRAY_SIZE(msm7x27a_pm_data));
Maheshkumar Sivasubramanianc6c55032011-10-25 16:01:32 -06002956 BUG_ON(msm_pm_boot_init(&msm_pm_boot_pdata));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002957
2958#if defined(CONFIG_I2C) && defined(CONFIG_GPIO_SX150X)
2959 register_i2c_devices();
2960#endif
2961#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
2962 bt_power_init();
2963#endif
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302964 if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002965 atmel_ts_pdata.min_x = 0;
2966 atmel_ts_pdata.max_x = 480;
2967 atmel_ts_pdata.min_y = 0;
2968 atmel_ts_pdata.max_y = 320;
2969 }
2970
2971 i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
2972 atmel_ts_i2c_info,
2973 ARRAY_SIZE(atmel_ts_i2c_info));
2974
Pankaj Kumar5be2a3e2011-09-26 11:45:02 +05302975#if defined(CONFIG_MSM_CAMERA)
Justin Paupored98328e2011-08-19 13:48:31 -07002976 msm_camera_vreg_init();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002977 i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
2978 i2c_camera_devices,
2979 ARRAY_SIZE(i2c_camera_devices));
Pankaj Kumar5be2a3e2011-09-26 11:45:02 +05302980#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002981 platform_device_register(&kp_pdev);
2982 platform_device_register(&hs_pdev);
2983
2984 /* configure it as a pdm function*/
2985 if (gpio_tlmm_config(GPIO_CFG(LED_GPIO_PDM, 3,
2986 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
2987 GPIO_CFG_8MA), GPIO_CFG_ENABLE))
2988 pr_err("%s: gpio_tlmm_config for %d failed\n",
2989 __func__, LED_GPIO_PDM);
2990 else
2991 platform_device_register(&led_pdev);
2992
2993#ifdef CONFIG_MSM_RPC_VIBRATOR
Trilok Soni3d0f6c52011-07-26 16:06:58 +05302994 if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002995 msm_init_pmic_vibrator();
2996#endif
2997 /*7x25a kgsl initializations*/
2998 msm7x25a_kgsl_3d0_init();
2999}
3000
3001static void __init msm7x2x_init_early(void)
3002{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003003 msm_msm7x2x_allocate_memory_regions();
3004}
3005
3006MACHINE_START(MSM7X27A_RUMI3, "QCT MSM7x27a RUMI3")
3007 .boot_params = PHYS_OFFSET + 0x100,
3008 .map_io = msm_common_io_init,
3009 .reserve = msm7x27a_reserve,
3010 .init_irq = msm_init_irq,
Trilok Soni16f61af2011-07-26 16:06:58 +05303011 .init_machine = msm7627a_rumi3_init,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003012 .timer = &msm_timer,
3013 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303014 .handle_irq = vic_handle_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003015MACHINE_END
3016MACHINE_START(MSM7X27A_SURF, "QCT MSM7x27a SURF")
3017 .boot_params = PHYS_OFFSET + 0x100,
3018 .map_io = msm_common_io_init,
3019 .reserve = msm7x27a_reserve,
3020 .init_irq = msm_init_irq,
3021 .init_machine = msm7x2x_init,
3022 .timer = &msm_timer,
3023 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303024 .handle_irq = vic_handle_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003025MACHINE_END
3026MACHINE_START(MSM7X27A_FFA, "QCT MSM7x27a FFA")
3027 .boot_params = PHYS_OFFSET + 0x100,
3028 .map_io = msm_common_io_init,
3029 .reserve = msm7x27a_reserve,
3030 .init_irq = msm_init_irq,
3031 .init_machine = msm7x2x_init,
3032 .timer = &msm_timer,
3033 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303034 .handle_irq = vic_handle_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003035MACHINE_END
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303036MACHINE_START(MSM7625A_SURF, "QCT MSM7625a SURF")
3037 .boot_params = PHYS_OFFSET + 0x100,
3038 .map_io = msm_common_io_init,
3039 .reserve = msm7x27a_reserve,
3040 .init_irq = msm_init_irq,
3041 .init_machine = msm7x2x_init,
3042 .timer = &msm_timer,
3043 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303044 .handle_irq = vic_handle_irq,
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303045MACHINE_END
3046MACHINE_START(MSM7625A_FFA, "QCT MSM7625a FFA")
3047 .boot_params = PHYS_OFFSET + 0x100,
3048 .map_io = msm_common_io_init,
3049 .reserve = msm7x27a_reserve,
3050 .init_irq = msm_init_irq,
3051 .init_machine = msm7x2x_init,
3052 .timer = &msm_timer,
3053 .init_early = msm7x2x_init_early,
Taniya Das86e0e132011-10-19 11:32:00 +05303054 .handle_irq = vic_handle_irq,
Trilok Soni3d0f6c52011-07-26 16:06:58 +05303055MACHINE_END