blob: 792f42bf4d6d87e62c2ca94055aaea7c14967d2e [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
Steve Mucklea55df6e2010-01-07 12:43:24 -08002 *
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 *
Steve Mucklea55df6e2010-01-07 12:43:24 -080012 */
13
14#include <linux/kernel.h>
15#include <linux/platform_device.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070016#include <linux/gpio.h>
Steve Muckle9161d302010-02-11 11:50:40 -080017#include <linux/irq.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070018#include <linux/io.h>
19#include <linux/mfd/pmic8058.h>
Steve Mucklea55df6e2010-01-07 12:43:24 -080020
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070021#include <linux/input/pmic8058-keypad.h>
22#include <linux/pmic8058-batt-alarm.h>
23#include <linux/pmic8058-pwrkey.h>
Ashay Jaiswal4d1ab552011-07-15 11:30:49 +053024#include <linux/rtc/rtc-pm8058.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070025#include <linux/pmic8058-vibrator.h>
26#include <linux/leds.h>
27#include <linux/pmic8058-othc.h>
28#include <linux/mfd/pmic8901.h>
29#include <linux/regulator/pmic8058-regulator.h>
30#include <linux/regulator/pmic8901-regulator.h>
31#include <linux/bootmem.h>
32#include <linux/pwm.h>
33#include <linux/pmic8058-pwm.h>
34#include <linux/leds-pmic8058.h>
35#include <linux/pmic8058-xoadc.h>
36#include <linux/msm_adc.h>
37#include <linux/m_adcproc.h>
38#include <linux/mfd/marimba.h>
39#include <linux/msm-charger.h>
40#include <linux/i2c.h>
41#include <linux/i2c/sx150x.h>
42#include <linux/smsc911x.h>
43#include <linux/spi/spi.h>
44#include <linux/input/tdisc_shinetsu.h>
45#include <linux/input/cy8c_ts.h>
46#include <linux/cyttsp.h>
47#include <linux/i2c/isa1200.h>
48#include <linux/dma-mapping.h>
49#include <linux/i2c/bq27520.h>
50
51#ifdef CONFIG_ANDROID_PMEM
52#include <linux/android_pmem.h>
53#endif
54
55#if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
56#include <linux/i2c/smb137b.h>
57#endif
Steve Mucklea55df6e2010-01-07 12:43:24 -080058#include <asm/mach-types.h>
59#include <asm/mach/arch.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070060#include <asm/setup.h>
Steve Mucklea55df6e2010-01-07 12:43:24 -080061
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070062#include <mach/dma.h>
63#include <mach/mpp.h>
Steve Mucklea55df6e2010-01-07 12:43:24 -080064#include <mach/board.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070065#include <mach/irqs.h>
66#include <mach/msm_spi.h>
67#include <mach/msm_serial_hs.h>
68#include <mach/msm_serial_hs_lite.h>
Steve Mucklea55df6e2010-01-07 12:43:24 -080069#include <mach/msm_iomap.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070070#include <mach/msm_memtypes.h>
71#include <asm/mach/mmc.h>
72#include <mach/msm_battery.h>
73#include <mach/msm_hsusb.h>
Rohit Vaswania513aa8d2011-07-18 15:14:28 -070074#include <mach/gpiomux.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075#ifdef CONFIG_MSM_DSPS
76#include <mach/msm_dsps.h>
77#endif
78#include <mach/msm_xo.h>
79#include <mach/msm_bus_board.h>
80#include <mach/socinfo.h>
81#include <linux/i2c/isl9519.h>
82#ifdef CONFIG_USB_G_ANDROID
83#include <linux/usb/android.h>
84#include <mach/usbdiag.h>
85#endif
86#include <linux/regulator/consumer.h>
87#include <linux/regulator/machine.h>
88#include <mach/sdio_al.h>
89#include <mach/rpm.h>
90#include <mach/rpm-regulator.h>
Steve Mucklea55df6e2010-01-07 12:43:24 -080091
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070092#include "devices.h"
93#include "devices-msm8x60.h"
94#include "cpuidle.h"
95#include "pm.h"
96#include "mpm.h"
97#include "spm.h"
98#include "rpm_log.h"
99#include "timer.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100#include "gpiomux-8x60.h"
101#include "rpm_stats.h"
102#include "peripheral-loader.h"
103#include <linux/platform_data/qcom_crypto_device.h>
104#include "rpm_resources.h"
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700105#include "acpuclock.h"
Steve Mucklea55df6e2010-01-07 12:43:24 -0800106
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700107#define MSM_SHARED_RAM_PHYS 0x40000000
108
109/* Macros assume PMIC GPIOs start at 0 */
110#define PM8058_GPIO_BASE NR_MSM_GPIOS
111#define PM8058_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_GPIO_BASE)
112#define PM8058_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - PM8058_GPIO_BASE)
113#define PM8058_MPP_BASE (PM8058_GPIO_BASE + PM8058_GPIOS)
114#define PM8058_MPP_PM_TO_SYS(pm_gpio) (pm_gpio + PM8058_MPP_BASE)
115#define PM8058_MPP_SYS_TO_PM(sys_gpio) (sys_gpio - PM8058_MPP_BASE)
116#define PM8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS)
117
118#define PM8901_GPIO_BASE (PM8058_GPIO_BASE + \
119 PM8058_GPIOS + PM8058_MPPS)
120#define PM8901_GPIO_PM_TO_SYS(pm_gpio) (pm_gpio + PM8901_GPIO_BASE)
121#define PM8901_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - PM901_GPIO_BASE)
122#define PM8901_IRQ_BASE (PM8058_IRQ_BASE + \
123 NR_PMIC8058_IRQS)
124
125#define MDM2AP_SYNC 129
126
Terence Hampson1c73fef2011-07-19 17:10:49 -0400127#define GPIO_ETHERNET_RESET_N_DRAGON 30
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700128#define LCDC_SPI_GPIO_CLK 73
129#define LCDC_SPI_GPIO_CS 72
130#define LCDC_SPI_GPIO_MOSI 70
131#define LCDC_AUO_PANEL_NAME "lcdc_auo_wvga"
132#define LCDC_SAMSUNG_OLED_PANEL_NAME "lcdc_samsung_oled"
133#define LCDC_SAMSUNG_WSVGA_PANEL_NAME "lcdc_samsung_wsvga"
134#define LCDC_SAMSUNG_SPI_DEVICE_NAME "lcdc_samsung_ams367pe02"
135#define LCDC_AUO_SPI_DEVICE_NAME "lcdc_auo_nt35582"
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -0400136#define LCDC_NT35582_PANEL_NAME "lcdc_nt35582_wvga"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137
138#define DSPS_PIL_GENERIC_NAME "dsps"
139#define DSPS_PIL_FLUID_NAME "dsps_fluid"
140
141enum {
142 GPIO_EXPANDER_IRQ_BASE = PM8901_IRQ_BASE + NR_PMIC8901_IRQS,
143 GPIO_EXPANDER_GPIO_BASE = PM8901_GPIO_BASE + PM8901_MPPS,
144 /* CORE expander */
145 GPIO_CORE_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
146 GPIO_CLASS_D1_EN = GPIO_CORE_EXPANDER_BASE,
147 GPIO_WLAN_DEEP_SLEEP_N,
148 GPIO_LVDS_SHUTDOWN_N,
149 GPIO_DISP_RESX_N = GPIO_LVDS_SHUTDOWN_N,
150 GPIO_MS_SYS_RESET_N,
151 GPIO_CAP_TS_RESOUT_N,
152 GPIO_CAP_GAUGE_BI_TOUT,
153 GPIO_ETHERNET_PME,
154 GPIO_EXT_GPS_LNA_EN,
155 GPIO_MSM_WAKES_BT,
156 GPIO_ETHERNET_RESET_N,
157 GPIO_HEADSET_DET_N,
158 GPIO_USB_UICC_EN,
159 GPIO_BACKLIGHT_EN,
160 GPIO_EXT_CAMIF_PWR_EN,
161 GPIO_BATT_GAUGE_INT_N,
162 GPIO_BATT_GAUGE_EN,
163 /* DOCKING expander */
164 GPIO_DOCKING_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE + 16,
165 GPIO_MIPI_DSI_RST_N = GPIO_DOCKING_EXPANDER_BASE,
166 GPIO_AUX_JTAG_DET_N,
167 GPIO_DONGLE_DET_N,
168 GPIO_SVIDEO_LOAD_DET,
169 GPIO_SVID_AMP_SHUTDOWN1_N,
170 GPIO_SVID_AMP_SHUTDOWN0_N,
171 GPIO_SDC_WP,
172 GPIO_IRDA_PWDN,
173 GPIO_IRDA_RESET_N,
174 GPIO_DONGLE_GPIO0,
175 GPIO_DONGLE_GPIO1,
176 GPIO_DONGLE_GPIO2,
177 GPIO_DONGLE_GPIO3,
178 GPIO_DONGLE_PWR_EN,
179 GPIO_EMMC_RESET_N,
180 GPIO_TP_EXP2_IO15,
181 /* SURF expander */
182 GPIO_SURF_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE + (16 * 2),
183 GPIO_SD_CARD_DET_1 = GPIO_SURF_EXPANDER_BASE,
184 GPIO_SD_CARD_DET_2,
185 GPIO_SD_CARD_DET_4,
186 GPIO_SD_CARD_DET_5,
187 GPIO_UIM3_RST,
188 GPIO_SURF_EXPANDER_IO5,
189 GPIO_SURF_EXPANDER_IO6,
190 GPIO_ADC_I2C_EN,
191 GPIO_SURF_EXPANDER_IO8,
192 GPIO_SURF_EXPANDER_IO9,
193 GPIO_SURF_EXPANDER_IO10,
194 GPIO_SURF_EXPANDER_IO11,
195 GPIO_SURF_EXPANDER_IO12,
196 GPIO_SURF_EXPANDER_IO13,
197 GPIO_SURF_EXPANDER_IO14,
198 GPIO_SURF_EXPANDER_IO15,
199 /* LEFT KB IO expander */
200 GPIO_LEFT_KB_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE + (16 * 3),
201 GPIO_LEFT_LED_1 = GPIO_LEFT_KB_EXPANDER_BASE,
202 GPIO_LEFT_LED_2,
203 GPIO_LEFT_LED_3,
204 GPIO_LEFT_LED_WLAN,
205 GPIO_JOYSTICK_EN,
206 GPIO_CAP_TS_SLEEP,
207 GPIO_LEFT_KB_IO6,
208 GPIO_LEFT_LED_5,
209 /* RIGHT KB IO expander */
210 GPIO_RIGHT_KB_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE + (16 * 3) + 8,
211 GPIO_RIGHT_LED_1 = GPIO_RIGHT_KB_EXPANDER_BASE,
212 GPIO_RIGHT_LED_2,
213 GPIO_RIGHT_LED_3,
214 GPIO_RIGHT_LED_BT,
215 GPIO_WEB_CAMIF_STANDBY,
216 GPIO_COMPASS_RST_N,
217 GPIO_WEB_CAMIF_RESET_N,
218 GPIO_RIGHT_LED_5,
219 GPIO_R_ALTIMETER_RESET_N,
220 /* FLUID S IO expander */
221 GPIO_SOUTH_EXPANDER_BASE,
222 GPIO_MIC2_ANCR_SEL = GPIO_SOUTH_EXPANDER_BASE,
223 GPIO_MIC1_ANCL_SEL,
224 GPIO_HS_MIC4_SEL,
225 GPIO_FML_MIC3_SEL,
226 GPIO_FMR_MIC5_SEL,
227 GPIO_TS_SLEEP,
228 GPIO_HAP_SHIFT_LVL_OE,
229 GPIO_HS_SW_DIR,
230 /* FLUID N IO expander */
231 GPIO_NORTH_EXPANDER_BASE,
232 GPIO_EPM_3_3V_EN = GPIO_NORTH_EXPANDER_BASE,
233 GPIO_EPM_5V_BOOST_EN,
234 GPIO_AUX_CAM_2P7_EN,
235 GPIO_LED_FLASH_EN,
236 GPIO_LED1_GREEN_N,
237 GPIO_LED2_RED_N,
238 GPIO_FRONT_CAM_RESET_N,
239 GPIO_EPM_LVLSFT_EN,
240 GPIO_N_ALTIMETER_RESET_N,
241 /* EPM expander */
242 GPIO_EPM_EXPANDER_BASE,
243 GPIO_PWR_MON_START = GPIO_EPM_EXPANDER_BASE,
244 GPIO_PWR_MON_RESET_N,
245 GPIO_ADC1_PWDN_N,
246 GPIO_ADC2_PWDN_N,
247 GPIO_EPM_EXPANDER_IO4,
248 GPIO_ADC1_MUX_SPI_INT_N_3_3V,
249 GPIO_ADC2_MUX_SPI_INT_N,
250 GPIO_EPM_EXPANDER_IO7,
251 GPIO_PWR_MON_ENABLE,
252 GPIO_EPM_SPI_ADC1_CS_N,
253 GPIO_EPM_SPI_ADC2_CS_N,
254 GPIO_EPM_EXPANDER_IO11,
255 GPIO_EPM_EXPANDER_IO12,
256 GPIO_EPM_EXPANDER_IO13,
257 GPIO_EPM_EXPANDER_IO14,
258 GPIO_EPM_EXPANDER_IO15,
259};
260
261/*
262 * The UI_INTx_N lines are pmic gpio lines which connect i2c
263 * gpio expanders to the pm8058.
264 */
265#define UI_INT1_N 25
266#define UI_INT2_N 34
267#define UI_INT3_N 14
268/*
269FM GPIO is GPIO 18 on PMIC 8058.
270As the index starts from 0 in the PMIC driver, and hence 17
271corresponds to GPIO 18 on PMIC 8058.
272*/
273#define FM_GPIO 17
274
275#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
276static void (*sdc2_status_notify_cb)(int card_present, void *dev_id);
277static void *sdc2_status_notify_cb_devid;
278#endif
279
280#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
281static void (*sdc5_status_notify_cb)(int card_present, void *dev_id);
282static void *sdc5_status_notify_cb_devid;
283#endif
284
285static struct msm_spm_platform_data msm_spm_data_v1[] __initdata = {
286 [0] = {
287 .reg_base_addr = MSM_SAW0_BASE,
288
289#ifdef CONFIG_MSM_AVS_HW
290 .reg_init_values[MSM_SPM_REG_SAW_AVS_CTL] = 0x586020FF,
291#endif
292 .reg_init_values[MSM_SPM_REG_SAW_CFG] = 0x0F,
293 .reg_init_values[MSM_SPM_REG_SAW_SPM_CTL] = 0x68,
294 .reg_init_values[MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY] = 0xFFFFFFFF,
295 .reg_init_values[MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY] = 0xFFFFFFFF,
296
297 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLK_EN] = 0x01,
298 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN] = 0x07,
299 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN] = 0x00,
300
301 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLMP_EN] = 0x01,
302 .reg_init_values[MSM_SPM_REG_SAW_SLP_RST_EN] = 0x00,
303 .reg_init_values[MSM_SPM_REG_SAW_SPM_MPM_CFG] = 0x00,
304
305 .awake_vlevel = 0x94,
306 .retention_vlevel = 0x81,
307 .collapse_vlevel = 0x20,
308 .retention_mid_vlevel = 0x94,
309 .collapse_mid_vlevel = 0x8C,
310
311 .vctl_timeout_us = 50,
312 },
313
314 [1] = {
315 .reg_base_addr = MSM_SAW1_BASE,
316
317#ifdef CONFIG_MSM_AVS_HW
318 .reg_init_values[MSM_SPM_REG_SAW_AVS_CTL] = 0x586020FF,
319#endif
320 .reg_init_values[MSM_SPM_REG_SAW_CFG] = 0x0F,
321 .reg_init_values[MSM_SPM_REG_SAW_SPM_CTL] = 0x68,
322 .reg_init_values[MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY] = 0xFFFFFFFF,
323 .reg_init_values[MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY] = 0xFFFFFFFF,
324
325 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLK_EN] = 0x13,
326 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN] = 0x07,
327 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN] = 0x00,
328
329 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLMP_EN] = 0x01,
330 .reg_init_values[MSM_SPM_REG_SAW_SLP_RST_EN] = 0x00,
331 .reg_init_values[MSM_SPM_REG_SAW_SPM_MPM_CFG] = 0x00,
332
333 .awake_vlevel = 0x94,
334 .retention_vlevel = 0x81,
335 .collapse_vlevel = 0x20,
336 .retention_mid_vlevel = 0x94,
337 .collapse_mid_vlevel = 0x8C,
338
339 .vctl_timeout_us = 50,
340 },
341};
342
343static struct msm_spm_platform_data msm_spm_data[] __initdata = {
344 [0] = {
345 .reg_base_addr = MSM_SAW0_BASE,
346
347#ifdef CONFIG_MSM_AVS_HW
348 .reg_init_values[MSM_SPM_REG_SAW_AVS_CTL] = 0x586020FF,
349#endif
350 .reg_init_values[MSM_SPM_REG_SAW_CFG] = 0x1C,
351 .reg_init_values[MSM_SPM_REG_SAW_SPM_CTL] = 0x68,
352 .reg_init_values[MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY] = 0x0C0CFFFF,
353 .reg_init_values[MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY] = 0x78780FFF,
354
355 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLK_EN] = 0x01,
356 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN] = 0x07,
357 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN] = 0x00,
358
359 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLMP_EN] = 0x01,
360 .reg_init_values[MSM_SPM_REG_SAW_SLP_RST_EN] = 0x00,
361 .reg_init_values[MSM_SPM_REG_SAW_SPM_MPM_CFG] = 0x00,
362
363 .awake_vlevel = 0xA0,
364 .retention_vlevel = 0x89,
365 .collapse_vlevel = 0x20,
366 .retention_mid_vlevel = 0x89,
367 .collapse_mid_vlevel = 0x89,
368
369 .vctl_timeout_us = 50,
370 },
371
372 [1] = {
373 .reg_base_addr = MSM_SAW1_BASE,
374
375#ifdef CONFIG_MSM_AVS_HW
376 .reg_init_values[MSM_SPM_REG_SAW_AVS_CTL] = 0x586020FF,
377#endif
378 .reg_init_values[MSM_SPM_REG_SAW_CFG] = 0x1C,
379 .reg_init_values[MSM_SPM_REG_SAW_SPM_CTL] = 0x68,
380 .reg_init_values[MSM_SPM_REG_SAW_SPM_SLP_TMR_DLY] = 0x0C0CFFFF,
381 .reg_init_values[MSM_SPM_REG_SAW_SPM_WAKE_TMR_DLY] = 0x78780FFF,
382
383 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLK_EN] = 0x13,
384 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_PRECLMP_EN] = 0x07,
385 .reg_init_values[MSM_SPM_REG_SAW_SLP_HSFS_POSTCLMP_EN] = 0x00,
386
387 .reg_init_values[MSM_SPM_REG_SAW_SLP_CLMP_EN] = 0x01,
388 .reg_init_values[MSM_SPM_REG_SAW_SLP_RST_EN] = 0x00,
389 .reg_init_values[MSM_SPM_REG_SAW_SPM_MPM_CFG] = 0x00,
390
391 .awake_vlevel = 0xA0,
392 .retention_vlevel = 0x89,
393 .collapse_vlevel = 0x20,
394 .retention_mid_vlevel = 0x89,
395 .collapse_mid_vlevel = 0x89,
396
397 .vctl_timeout_us = 50,
398 },
399};
400
Matt Wagantall6d9ebee2011-08-26 12:15:24 -0700401static struct acpuclk_platform_data msm8x60_acpuclk_data __initdata = {
402 .init = acpuclk_8x60_init,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700403};
404
405/*
406 * Consumer specific regulator names:
407 * regulator name consumer dev_name
408 */
409static struct regulator_consumer_supply vreg_consumers_8901_S0[] = {
410 REGULATOR_SUPPLY("8901_s0", NULL),
411};
412static struct regulator_consumer_supply vreg_consumers_8901_S1[] = {
413 REGULATOR_SUPPLY("8901_s1", NULL),
414};
415
416static struct regulator_init_data saw_s0_init_data = {
417 .constraints = {
418 .name = "8901_s0",
419 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
420 .min_uV = 840000,
421 .max_uV = 1250000,
422 },
423 .consumer_supplies = vreg_consumers_8901_S0,
424 .num_consumer_supplies = ARRAY_SIZE(vreg_consumers_8901_S0),
425};
426
427static struct regulator_init_data saw_s1_init_data = {
428 .constraints = {
429 .name = "8901_s1",
430 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
431 .min_uV = 840000,
432 .max_uV = 1250000,
433 },
434 .consumer_supplies = vreg_consumers_8901_S1,
435 .num_consumer_supplies = ARRAY_SIZE(vreg_consumers_8901_S1),
436};
437
438static struct platform_device msm_device_saw_s0 = {
439 .name = "saw-regulator",
440 .id = 0,
441 .dev = {
442 .platform_data = &saw_s0_init_data,
443 },
444};
445
446static struct platform_device msm_device_saw_s1 = {
447 .name = "saw-regulator",
448 .id = 1,
449 .dev = {
450 .platform_data = &saw_s1_init_data,
451 },
452};
453
454/*
455 * The smc91x configuration varies depending on platform.
456 * The resources data structure is filled in at runtime.
457 */
458static struct resource smc91x_resources[] = {
459 [0] = {
460 .flags = IORESOURCE_MEM,
461 },
462 [1] = {
463 .flags = IORESOURCE_IRQ,
464 },
465};
466
467static struct platform_device smc91x_device = {
468 .name = "smc91x",
469 .id = 0,
470 .num_resources = ARRAY_SIZE(smc91x_resources),
471 .resource = smc91x_resources,
472};
473
474static struct resource smsc911x_resources[] = {
475 [0] = {
476 .flags = IORESOURCE_MEM,
477 .start = 0x1b800000,
478 .end = 0x1b8000ff
479 },
480 [1] = {
481 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
482 },
483};
484
485static struct smsc911x_platform_config smsc911x_config = {
486 .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
487 .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
488 .flags = SMSC911X_USE_16BIT,
489 .has_reset_gpio = 1,
490 .reset_gpio = GPIO_ETHERNET_RESET_N
491};
492
493static struct platform_device smsc911x_device = {
494 .name = "smsc911x",
495 .id = 0,
496 .num_resources = ARRAY_SIZE(smsc911x_resources),
497 .resource = smsc911x_resources,
498 .dev = {
499 .platform_data = &smsc911x_config
500 }
501};
502
503#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
504 defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE) || \
505 defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
506 defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
507
508#define QCE_SIZE 0x10000
509#define QCE_0_BASE 0x18500000
510
511#define QCE_HW_KEY_SUPPORT 0
512#define QCE_SHA_HMAC_SUPPORT 0
513#define QCE_SHARE_CE_RESOURCE 2
514#define QCE_CE_SHARED 1
515
516static struct resource qcrypto_resources[] = {
517 [0] = {
518 .start = QCE_0_BASE,
519 .end = QCE_0_BASE + QCE_SIZE - 1,
520 .flags = IORESOURCE_MEM,
521 },
522 [1] = {
523 .name = "crypto_channels",
524 .start = DMOV_CE_IN_CHAN,
525 .end = DMOV_CE_OUT_CHAN,
526 .flags = IORESOURCE_DMA,
527 },
528 [2] = {
529 .name = "crypto_crci_in",
530 .start = DMOV_CE_IN_CRCI,
531 .end = DMOV_CE_IN_CRCI,
532 .flags = IORESOURCE_DMA,
533 },
534 [3] = {
535 .name = "crypto_crci_out",
536 .start = DMOV_CE_OUT_CRCI,
537 .end = DMOV_CE_OUT_CRCI,
538 .flags = IORESOURCE_DMA,
539 },
540 [4] = {
541 .name = "crypto_crci_hash",
542 .start = DMOV_CE_HASH_CRCI,
543 .end = DMOV_CE_HASH_CRCI,
544 .flags = IORESOURCE_DMA,
545 },
546};
547
548static struct resource qcedev_resources[] = {
549 [0] = {
550 .start = QCE_0_BASE,
551 .end = QCE_0_BASE + QCE_SIZE - 1,
552 .flags = IORESOURCE_MEM,
553 },
554 [1] = {
555 .name = "crypto_channels",
556 .start = DMOV_CE_IN_CHAN,
557 .end = DMOV_CE_OUT_CHAN,
558 .flags = IORESOURCE_DMA,
559 },
560 [2] = {
561 .name = "crypto_crci_in",
562 .start = DMOV_CE_IN_CRCI,
563 .end = DMOV_CE_IN_CRCI,
564 .flags = IORESOURCE_DMA,
565 },
566 [3] = {
567 .name = "crypto_crci_out",
568 .start = DMOV_CE_OUT_CRCI,
569 .end = DMOV_CE_OUT_CRCI,
570 .flags = IORESOURCE_DMA,
571 },
572 [4] = {
573 .name = "crypto_crci_hash",
574 .start = DMOV_CE_HASH_CRCI,
575 .end = DMOV_CE_HASH_CRCI,
576 .flags = IORESOURCE_DMA,
577 },
578};
579
580#endif
581
582#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
583 defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
584
585static struct msm_ce_hw_support qcrypto_ce_hw_suppport = {
586 .ce_shared = QCE_CE_SHARED,
587 .shared_ce_resource = QCE_SHARE_CE_RESOURCE,
588 .hw_key_support = QCE_HW_KEY_SUPPORT,
589 .sha_hmac = QCE_SHA_HMAC_SUPPORT,
590};
591
592static struct platform_device qcrypto_device = {
593 .name = "qcrypto",
594 .id = 0,
595 .num_resources = ARRAY_SIZE(qcrypto_resources),
596 .resource = qcrypto_resources,
597 .dev = {
598 .coherent_dma_mask = DMA_BIT_MASK(32),
599 .platform_data = &qcrypto_ce_hw_suppport,
600 },
601};
602#endif
603
604#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
605 defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
606
607static struct msm_ce_hw_support qcedev_ce_hw_suppport = {
608 .ce_shared = QCE_CE_SHARED,
609 .shared_ce_resource = QCE_SHARE_CE_RESOURCE,
610 .hw_key_support = QCE_HW_KEY_SUPPORT,
611 .sha_hmac = QCE_SHA_HMAC_SUPPORT,
612};
613
614static struct platform_device qcedev_device = {
615 .name = "qce",
616 .id = 0,
617 .num_resources = ARRAY_SIZE(qcedev_resources),
618 .resource = qcedev_resources,
619 .dev = {
620 .coherent_dma_mask = DMA_BIT_MASK(32),
621 .platform_data = &qcedev_ce_hw_suppport,
622 },
623};
624#endif
625
626#if defined(CONFIG_HAPTIC_ISA1200) || \
627 defined(CONFIG_HAPTIC_ISA1200_MODULE)
628
629static const char *vregs_isa1200_name[] = {
630 "8058_s3",
631 "8901_l4",
632};
633
634static const int vregs_isa1200_val[] = {
635 1800000,/* uV */
636 2600000,
637};
638static struct regulator *vregs_isa1200[ARRAY_SIZE(vregs_isa1200_name)];
639static struct msm_xo_voter *xo_handle_a1;
640
641static int isa1200_power(int vreg_on)
Steve Mucklea55df6e2010-01-07 12:43:24 -0800642{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700643 int i, rc = 0;
644
645 for (i = 0; i < ARRAY_SIZE(vregs_isa1200_name); i++) {
646 rc = vreg_on ? regulator_enable(vregs_isa1200[i]) :
647 regulator_disable(vregs_isa1200[i]);
648 if (rc < 0) {
649 pr_err("%s: vreg %s %s failed (%d)\n",
650 __func__, vregs_isa1200_name[i],
651 vreg_on ? "enable" : "disable", rc);
652 goto vreg_fail;
653 }
654 }
655
656 rc = vreg_on ? msm_xo_mode_vote(xo_handle_a1, MSM_XO_MODE_ON) :
657 msm_xo_mode_vote(xo_handle_a1, MSM_XO_MODE_OFF);
658 if (rc < 0) {
659 pr_err("%s: failed to %svote for TCXO A1 buffer%d\n",
660 __func__, vreg_on ? "" : "de-", rc);
661 goto vreg_fail;
662 }
663 return 0;
664
665vreg_fail:
666 while (i--)
667 !vreg_on ? regulator_enable(vregs_isa1200[i]) :
668 regulator_disable(vregs_isa1200[i]);
669 return rc;
Steve Mucklea55df6e2010-01-07 12:43:24 -0800670}
671
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700672static int isa1200_dev_setup(bool enable)
Steve Mucklea55df6e2010-01-07 12:43:24 -0800673{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700674 int i, rc;
Steve Muckle9161d302010-02-11 11:50:40 -0800675
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700676 if (enable == true) {
677 for (i = 0; i < ARRAY_SIZE(vregs_isa1200_name); i++) {
678 vregs_isa1200[i] = regulator_get(NULL,
679 vregs_isa1200_name[i]);
680 if (IS_ERR(vregs_isa1200[i])) {
681 pr_err("%s: regulator get of %s failed (%ld)\n",
682 __func__, vregs_isa1200_name[i],
683 PTR_ERR(vregs_isa1200[i]));
684 rc = PTR_ERR(vregs_isa1200[i]);
685 goto vreg_get_fail;
686 }
687 rc = regulator_set_voltage(vregs_isa1200[i],
688 vregs_isa1200_val[i], vregs_isa1200_val[i]);
689 if (rc) {
690 pr_err("%s: regulator_set_voltage(%s) failed\n",
691 __func__, vregs_isa1200_name[i]);
692 goto vreg_get_fail;
693 }
694 }
Steve Muckle9161d302010-02-11 11:50:40 -0800695
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700696 rc = gpio_request(GPIO_HAP_SHIFT_LVL_OE, "haptics_shft_lvl_oe");
697 if (rc) {
698 pr_err("%s: unable to request gpio %d (%d)\n",
699 __func__, GPIO_HAP_SHIFT_LVL_OE, rc);
700 goto vreg_get_fail;
701 }
Steve Muckle9161d302010-02-11 11:50:40 -0800702
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700703 rc = gpio_direction_output(GPIO_HAP_SHIFT_LVL_OE, 1);
704 if (rc) {
705 pr_err("%s: Unable to set direction\n", __func__);;
706 goto free_gpio;
707 }
708
709 xo_handle_a1 = msm_xo_get(MSM_XO_TCXO_A1, "isa1200");
710 if (IS_ERR(xo_handle_a1)) {
711 rc = PTR_ERR(xo_handle_a1);
712 pr_err("%s: failed to get the handle for A1(%d)\n",
713 __func__, rc);
714 goto gpio_set_dir;
715 }
716 } else {
717 gpio_set_value(GPIO_HAP_SHIFT_LVL_OE, 0);
718 gpio_free(GPIO_HAP_SHIFT_LVL_OE);
719
720 for (i = 0; i < ARRAY_SIZE(vregs_isa1200_name); i++)
721 regulator_put(vregs_isa1200[i]);
722
723 msm_xo_put(xo_handle_a1);
724 }
725
726 return 0;
727gpio_set_dir:
728 gpio_set_value(GPIO_HAP_SHIFT_LVL_OE, 0);
729free_gpio:
730 gpio_free(GPIO_HAP_SHIFT_LVL_OE);
731vreg_get_fail:
732 while (i)
733 regulator_put(vregs_isa1200[--i]);
734 return rc;
735}
736
737#define PMIC_GPIO_HAP_ENABLE 18 /* PMIC GPIO Number 19 */
738static struct isa1200_platform_data isa1200_1_pdata = {
739 .name = "vibrator",
740 .power_on = isa1200_power,
741 .dev_setup = isa1200_dev_setup,
742 /*gpio to enable haptic*/
743 .hap_en_gpio = PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
744 .max_timeout = 15000,
745 .mode_ctrl = PWM_GEN_MODE,
746 .pwm_fd = {
747 .pwm_div = 256,
748 },
749 .is_erm = false,
750 .smart_en = true,
751 .ext_clk_en = true,
752 .chip_en = 1,
753};
754
755static struct i2c_board_info msm_isa1200_board_info[] = {
756 {
757 I2C_BOARD_INFO("isa1200_1", 0x90>>1),
758 .platform_data = &isa1200_1_pdata,
759 },
760};
761#endif
762
763#if defined(CONFIG_BATTERY_BQ27520) || \
764 defined(CONFIG_BATTERY_BQ27520_MODULE)
765static struct bq27520_platform_data bq27520_pdata = {
766 .name = "fuel-gauge",
767 .vreg_name = "8058_s3",
768 .vreg_value = 1800000,
769 .soc_int = GPIO_BATT_GAUGE_INT_N,
770 .bi_tout = GPIO_CAP_GAUGE_BI_TOUT,
771 .chip_en = GPIO_BATT_GAUGE_EN,
772 .enable_dlog = 0, /* if enable coulomb counter logger */
773};
774
775static struct i2c_board_info msm_bq27520_board_info[] = {
776 {
777 I2C_BOARD_INFO("bq27520", 0xaa>>1),
778 .platform_data = &bq27520_pdata,
779 },
780};
781#endif
782
783static struct msm_pm_platform_data msm_pm_data[MSM_PM_SLEEP_MODE_NR * 2] = {
784 [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
785 .idle_supported = 1,
786 .suspend_supported = 1,
787 .idle_enabled = 0,
788 .suspend_enabled = 0,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700789 },
790
791 [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
792 .idle_supported = 1,
793 .suspend_supported = 1,
794 .idle_enabled = 0,
795 .suspend_enabled = 0,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700796 },
797
798 [MSM_PM_MODE(0, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
799 .idle_supported = 1,
800 .suspend_supported = 1,
801 .idle_enabled = 1,
802 .suspend_enabled = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700803 },
804
805 [MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE)] = {
806 .idle_supported = 1,
807 .suspend_supported = 1,
808 .idle_enabled = 0,
809 .suspend_enabled = 0,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700810 },
811
812 [MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE)] = {
813 .idle_supported = 1,
814 .suspend_supported = 1,
815 .idle_enabled = 0,
816 .suspend_enabled = 0,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700817 },
818
819 [MSM_PM_MODE(1, MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT)] = {
820 .idle_supported = 1,
821 .suspend_supported = 1,
822 .idle_enabled = 1,
823 .suspend_enabled = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700824 },
825};
826
827static struct msm_cpuidle_state msm_cstates[] __initdata = {
828 {0, 0, "C0", "WFI",
829 MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
830
831 {0, 1, "C1", "STANDALONE_POWER_COLLAPSE",
832 MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
833
834 {0, 2, "C2", "POWER_COLLAPSE",
835 MSM_PM_SLEEP_MODE_POWER_COLLAPSE},
836
837 {1, 0, "C0", "WFI",
838 MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT},
839
840 {1, 1, "C1", "STANDALONE_POWER_COLLAPSE",
841 MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE},
842};
843
844static struct msm_rpmrs_level msm_rpmrs_levels[] __initdata = {
845 {
846 MSM_PM_SLEEP_MODE_WAIT_FOR_INTERRUPT,
847 MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
848 true,
849 1, 8000, 100000, 1,
850 },
851
852 {
853 MSM_PM_SLEEP_MODE_POWER_COLLAPSE_STANDALONE,
854 MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
855 true,
856 1500, 5000, 60100000, 3000,
857 },
858
859 {
860 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
861 MSM_RPMRS_LIMITS(ON, ACTIVE, MAX, ACTIVE),
862 false,
863 1800, 5000, 60350000, 3500,
864 },
865 {
866 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
867 MSM_RPMRS_LIMITS(OFF, ACTIVE, MAX, ACTIVE),
868 false,
869 3800, 4500, 65350000, 5500,
870 },
871
872 {
873 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
874 MSM_RPMRS_LIMITS(ON, HSFS_OPEN, MAX, ACTIVE),
875 false,
876 2800, 2500, 66850000, 4800,
877 },
878
879 {
880 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
881 MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, MAX, ACTIVE),
882 false,
883 4800, 2000, 71850000, 6800,
884 },
885
886 {
887 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
888 MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, ACTIVE, RET_HIGH),
889 false,
890 6800, 500, 75850000, 8800,
891 },
892
893 {
894 MSM_PM_SLEEP_MODE_POWER_COLLAPSE,
895 MSM_RPMRS_LIMITS(OFF, HSFS_OPEN, RET_HIGH, RET_LOW),
896 false,
897 7800, 0, 76350000, 9800,
898 },
899};
900
901#if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
902
903#define ISP1763_INT_GPIO 117
904#define ISP1763_RST_GPIO 152
905static struct resource isp1763_resources[] = {
906 [0] = {
907 .flags = IORESOURCE_MEM,
908 .start = 0x1D000000,
909 .end = 0x1D005FFF, /* 24KB */
910 },
911 [1] = {
912 .flags = IORESOURCE_IRQ,
913 },
914};
915static void __init msm8x60_cfg_isp1763(void)
916{
917 isp1763_resources[1].start = gpio_to_irq(ISP1763_INT_GPIO);
918 isp1763_resources[1].end = gpio_to_irq(ISP1763_INT_GPIO);
919}
920
921static int isp1763_setup_gpio(int enable)
922{
923 int status = 0;
924
925 if (enable) {
926 status = gpio_request(ISP1763_INT_GPIO, "isp1763_usb");
927 if (status) {
928 pr_err("%s:Failed to request GPIO %d\n",
929 __func__, ISP1763_INT_GPIO);
930 return status;
931 }
932 status = gpio_direction_input(ISP1763_INT_GPIO);
933 if (status) {
934 pr_err("%s:Failed to configure GPIO %d\n",
935 __func__, ISP1763_INT_GPIO);
936 goto gpio_free_int;
937 }
938 status = gpio_request(ISP1763_RST_GPIO, "isp1763_usb");
939 if (status) {
940 pr_err("%s:Failed to request GPIO %d\n",
941 __func__, ISP1763_RST_GPIO);
942 goto gpio_free_int;
943 }
944 status = gpio_direction_output(ISP1763_RST_GPIO, 1);
945 if (status) {
946 pr_err("%s:Failed to configure GPIO %d\n",
947 __func__, ISP1763_RST_GPIO);
948 goto gpio_free_rst;
949 }
950 pr_debug("\nISP GPIO configuration done\n");
951 return status;
952 }
953
954gpio_free_rst:
955 gpio_free(ISP1763_RST_GPIO);
956gpio_free_int:
957 gpio_free(ISP1763_INT_GPIO);
958
959 return status;
960}
961static struct isp1763_platform_data isp1763_pdata = {
962 .reset_gpio = ISP1763_RST_GPIO,
963 .setup_gpio = isp1763_setup_gpio
964};
965
966static struct platform_device isp1763_device = {
967 .name = "isp1763_usb",
968 .num_resources = ARRAY_SIZE(isp1763_resources),
969 .resource = isp1763_resources,
970 .dev = {
971 .platform_data = &isp1763_pdata
972 }
973};
974#endif
975
976#if defined(CONFIG_USB_GADGET_MSM_72K) || defined(CONFIG_USB_EHCI_MSM_72K)
977static struct regulator *ldo6_3p3;
978static struct regulator *ldo7_1p8;
979static struct regulator *vdd_cx;
980#define PMICID_INT PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 36)
981notify_vbus_state notify_vbus_state_func_ptr;
982static int usb_phy_susp_dig_vol = 750000;
983static int pmic_id_notif_supported;
984
985#ifdef CONFIG_USB_EHCI_MSM_72K
986#define USB_PMIC_ID_DET_DELAY msecs_to_jiffies(100)
987struct delayed_work pmic_id_det;
988
989static int __init usb_id_pin_rework_setup(char *support)
990{
991 if (strncmp(support, "true", 4) == 0)
992 pmic_id_notif_supported = 1;
993
994 return 1;
995}
996__setup("usb_id_pin_rework=", usb_id_pin_rework_setup);
997
998static void pmic_id_detect(struct work_struct *w)
999{
1000 int val = gpio_get_value_cansleep(PM8058_GPIO_PM_TO_SYS(36));
1001 pr_debug("%s(): gpio_read_value = %d\n", __func__, val);
1002
1003 if (notify_vbus_state_func_ptr)
1004 (*notify_vbus_state_func_ptr) (val);
1005}
1006
1007static irqreturn_t pmic_id_on_irq(int irq, void *data)
1008{
1009 /*
1010 * Spurious interrupts are observed on pmic gpio line
1011 * even though there is no state change on USB ID. Schedule the
1012 * work to to allow debounce on gpio
Steve Muckle9161d302010-02-11 11:50:40 -08001013 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001014 schedule_delayed_work(&pmic_id_det, USB_PMIC_ID_DET_DELAY);
Steve Muckle9161d302010-02-11 11:50:40 -08001015
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001016 return IRQ_HANDLED;
1017}
1018
1019static int msm_hsusb_pmic_id_notif_init(void (*callback)(int online), int init)
1020{
1021 unsigned ret = -ENODEV;
1022
1023 if (!callback)
1024 return -EINVAL;
1025
1026 if (machine_is_msm8x60_fluid())
1027 return -ENOTSUPP;
1028
1029 if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 2) {
1030 pr_debug("%s: USB_ID pin is not routed to PMIC"
1031 "on V1 surf/ffa\n", __func__);
1032 return -ENOTSUPP;
1033 }
1034
1035 if ((machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) &&
1036 !pmic_id_notif_supported) {
1037 pr_debug("%s: USB_ID is not routed to PMIC"
1038 "on V2 ffa\n", __func__);
1039 return -ENOTSUPP;
1040 }
1041
1042 usb_phy_susp_dig_vol = 500000;
1043
1044 if (init) {
1045 notify_vbus_state_func_ptr = callback;
1046 ret = pm8901_mpp_config_digital_out(1,
1047 PM8901_MPP_DIG_LEVEL_L5, 1);
1048 if (ret) {
1049 pr_err("%s: MPP2 configuration failed\n", __func__);
1050 return -ENODEV;
1051 }
1052 INIT_DELAYED_WORK(&pmic_id_det, pmic_id_detect);
1053 ret = request_threaded_irq(PMICID_INT, NULL, pmic_id_on_irq,
1054 (IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING),
1055 "msm_otg_id", NULL);
1056 if (ret) {
1057 pm8901_mpp_config_digital_out(1,
1058 PM8901_MPP_DIG_LEVEL_L5, 0);
1059 pr_err("%s:pmic_usb_id interrupt registration failed",
1060 __func__);
1061 return ret;
1062 }
1063 /* Notify the initial Id status */
1064 pmic_id_detect(&pmic_id_det.work);
1065 } else {
1066 free_irq(PMICID_INT, 0);
1067 cancel_delayed_work_sync(&pmic_id_det);
1068 notify_vbus_state_func_ptr = NULL;
1069 ret = pm8901_mpp_config_digital_out(1,
1070 PM8901_MPP_DIG_LEVEL_L5, 0);
1071 if (ret) {
1072 pr_err("%s:MPP2 configuration failed\n", __func__);
1073 return -ENODEV;
1074 }
1075 }
1076 return 0;
1077}
1078#endif
1079
1080#define USB_PHY_OPERATIONAL_MIN_VDD_DIG_VOL 1000000
1081#define USB_PHY_MAX_VDD_DIG_VOL 1320000
1082static int msm_hsusb_init_vddcx(int init)
1083{
1084 int ret = 0;
1085
1086 if (init) {
1087 vdd_cx = regulator_get(NULL, "8058_s1");
1088 if (IS_ERR(vdd_cx)) {
1089 return PTR_ERR(vdd_cx);
1090 }
1091
1092 ret = regulator_set_voltage(vdd_cx,
1093 USB_PHY_OPERATIONAL_MIN_VDD_DIG_VOL,
1094 USB_PHY_MAX_VDD_DIG_VOL);
1095 if (ret) {
1096 pr_err("%s: unable to set the voltage for regulator"
1097 "vdd_cx\n", __func__);
1098 regulator_put(vdd_cx);
1099 return ret;
1100 }
1101
1102 ret = regulator_enable(vdd_cx);
1103 if (ret) {
1104 pr_err("%s: unable to enable regulator"
1105 "vdd_cx\n", __func__);
1106 regulator_put(vdd_cx);
1107 }
1108 } else {
1109 ret = regulator_disable(vdd_cx);
1110 if (ret) {
1111 pr_err("%s: Unable to disable the regulator:"
1112 "vdd_cx\n", __func__);
1113 return ret;
1114 }
1115
1116 regulator_put(vdd_cx);
1117 }
1118
1119 return ret;
1120}
1121
1122static int msm_hsusb_config_vddcx(int high)
1123{
1124 int max_vol = USB_PHY_MAX_VDD_DIG_VOL;
1125 int min_vol;
1126 int ret;
1127
1128 if (high)
1129 min_vol = USB_PHY_OPERATIONAL_MIN_VDD_DIG_VOL;
1130 else
1131 min_vol = usb_phy_susp_dig_vol;
1132
1133 ret = regulator_set_voltage(vdd_cx, min_vol, max_vol);
1134 if (ret) {
1135 pr_err("%s: unable to set the voltage for regulator"
1136 "vdd_cx\n", __func__);
1137 return ret;
1138 }
1139
1140 pr_debug("%s: min_vol:%d max_vol:%d\n", __func__, min_vol, max_vol);
1141
1142 return ret;
1143}
1144
1145#define USB_PHY_3P3_VOL_MIN 3050000 /* uV */
1146#define USB_PHY_3P3_VOL_MAX 3050000 /* uV */
1147#define USB_PHY_3P3_HPM_LOAD 50000 /* uA */
1148#define USB_PHY_3P3_LPM_LOAD 4000 /* uA */
1149
1150#define USB_PHY_1P8_VOL_MIN 1800000 /* uV */
1151#define USB_PHY_1P8_VOL_MAX 1800000 /* uV */
1152#define USB_PHY_1P8_HPM_LOAD 50000 /* uA */
1153#define USB_PHY_1P8_LPM_LOAD 4000 /* uA */
1154static int msm_hsusb_ldo_init(int init)
1155{
1156 int rc = 0;
1157
1158 if (init) {
1159 ldo6_3p3 = regulator_get(NULL, "8058_l6");
1160 if (IS_ERR(ldo6_3p3))
1161 return PTR_ERR(ldo6_3p3);
1162
1163 ldo7_1p8 = regulator_get(NULL, "8058_l7");
1164 if (IS_ERR(ldo7_1p8)) {
1165 rc = PTR_ERR(ldo7_1p8);
1166 goto put_3p3;
1167 }
1168
1169 rc = regulator_set_voltage(ldo6_3p3, USB_PHY_3P3_VOL_MIN,
1170 USB_PHY_3P3_VOL_MAX);
1171 if (rc) {
1172 pr_err("%s: Unable to set voltage level for"
1173 "ldo6_3p3 regulator\n", __func__);
1174 goto put_1p8;
1175 }
1176 rc = regulator_enable(ldo6_3p3);
1177 if (rc) {
1178 pr_err("%s: Unable to enable the regulator:"
1179 "ldo6_3p3\n", __func__);
1180 goto put_1p8;
1181 }
1182 rc = regulator_set_voltage(ldo7_1p8, USB_PHY_1P8_VOL_MIN,
1183 USB_PHY_1P8_VOL_MAX);
1184 if (rc) {
1185 pr_err("%s: Unable to set voltage level for"
1186 "ldo7_1p8 regulator\n", __func__);
1187 goto disable_3p3;
1188 }
1189 rc = regulator_enable(ldo7_1p8);
1190 if (rc) {
1191 pr_err("%s: Unable to enable the regulator:"
1192 "ldo7_1p8\n", __func__);
1193 goto disable_3p3;
1194 }
1195
1196 return 0;
1197 }
1198
1199 regulator_disable(ldo7_1p8);
1200disable_3p3:
1201 regulator_disable(ldo6_3p3);
1202put_1p8:
1203 regulator_put(ldo7_1p8);
1204put_3p3:
1205 regulator_put(ldo6_3p3);
1206 return rc;
1207}
1208
1209static int msm_hsusb_ldo_enable(int on)
1210{
1211 int ret = 0;
1212
1213 if (!ldo7_1p8 || IS_ERR(ldo7_1p8)) {
1214 pr_err("%s: ldo7_1p8 is not initialized\n", __func__);
1215 return -ENODEV;
1216 }
1217
1218 if (!ldo6_3p3 || IS_ERR(ldo6_3p3)) {
1219 pr_err("%s: ldo6_3p3 is not initialized\n", __func__);
1220 return -ENODEV;
1221 }
1222
1223 if (on) {
1224 ret = regulator_set_optimum_mode(ldo7_1p8,
1225 USB_PHY_1P8_HPM_LOAD);
1226 if (ret < 0) {
1227 pr_err("%s: Unable to set HPM of the regulator:"
1228 "ldo7_1p8\n", __func__);
1229 return ret;
1230 }
1231 ret = regulator_set_optimum_mode(ldo6_3p3,
1232 USB_PHY_3P3_HPM_LOAD);
1233 if (ret < 0) {
1234 pr_err("%s: Unable to set HPM of the regulator:"
1235 "ldo6_3p3\n", __func__);
1236 regulator_set_optimum_mode(ldo7_1p8,
1237 USB_PHY_1P8_LPM_LOAD);
1238 return ret;
1239 }
1240 } else {
1241 ret = regulator_set_optimum_mode(ldo7_1p8,
1242 USB_PHY_1P8_LPM_LOAD);
1243 if (ret < 0)
1244 pr_err("%s: Unable to set LPM of the regulator:"
1245 "ldo7_1p8\n", __func__);
1246 ret = regulator_set_optimum_mode(ldo6_3p3,
1247 USB_PHY_3P3_LPM_LOAD);
1248 if (ret < 0)
1249 pr_err("%s: Unable to set LPM of the regulator:"
1250 "ldo6_3p3\n", __func__);
1251 }
1252
1253 pr_debug("reg (%s)\n", on ? "HPM" : "LPM");
1254 return ret < 0 ? ret : 0;
1255 }
1256#endif
1257#ifdef CONFIG_USB_EHCI_MSM_72K
1258#if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
1259static void msm_hsusb_smb137b_vbus_power(unsigned phy_info, int on)
1260{
1261 static int vbus_is_on;
1262
1263 /* If VBUS is already on (or off), do nothing. */
1264 if (on == vbus_is_on)
1265 return;
1266 smb137b_otg_power(on);
1267 vbus_is_on = on;
1268}
1269#endif
1270static void msm_hsusb_vbus_power(unsigned phy_info, int on)
1271{
1272 static struct regulator *votg_5v_switch;
1273 static struct regulator *ext_5v_reg;
1274 static int vbus_is_on;
1275
1276 /* If VBUS is already on (or off), do nothing. */
1277 if (on == vbus_is_on)
1278 return;
1279
1280 if (!votg_5v_switch) {
1281 votg_5v_switch = regulator_get(NULL, "8901_usb_otg");
1282 if (IS_ERR(votg_5v_switch)) {
1283 pr_err("%s: unable to get votg_5v_switch\n", __func__);
1284 return;
1285 }
1286 }
1287 if (!ext_5v_reg) {
1288 ext_5v_reg = regulator_get(NULL, "8901_mpp0");
1289 if (IS_ERR(ext_5v_reg)) {
1290 pr_err("%s: unable to get ext_5v_reg\n", __func__);
1291 return;
1292 }
1293 }
1294 if (on) {
1295 if (regulator_enable(ext_5v_reg)) {
1296 pr_err("%s: Unable to enable the regulator:"
1297 " ext_5v_reg\n", __func__);
1298 return;
1299 }
1300 if (regulator_enable(votg_5v_switch)) {
1301 pr_err("%s: Unable to enable the regulator:"
1302 " votg_5v_switch\n", __func__);
1303 return;
1304 }
1305 } else {
1306 if (regulator_disable(votg_5v_switch))
1307 pr_err("%s: Unable to enable the regulator:"
1308 " votg_5v_switch\n", __func__);
1309 if (regulator_disable(ext_5v_reg))
1310 pr_err("%s: Unable to enable the regulator:"
1311 " ext_5v_reg\n", __func__);
1312 }
1313
1314 vbus_is_on = on;
1315}
1316
1317static struct msm_usb_host_platform_data msm_usb_host_pdata = {
1318 .phy_info = (USB_PHY_INTEGRATED | USB_PHY_MODEL_45NM),
1319 .power_budget = 390,
1320};
1321#endif
1322
1323#ifdef CONFIG_BATTERY_MSM8X60
1324static int msm_hsusb_pmic_vbus_notif_init(void (*callback)(int online),
1325 int init)
1326{
1327 int ret = -ENOTSUPP;
1328
1329#if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
1330 if (machine_is_msm8x60_fluid()) {
1331 if (init)
1332 msm_charger_register_vbus_sn(callback);
1333 else
1334 msm_charger_unregister_vbus_sn(callback);
1335 return 0;
1336 }
1337#endif
1338 /* ID and VBUS lines are connected to pmic on 8660.V2.SURF,
1339 * hence, irrespective of either peripheral only mode or
1340 * OTG (host and peripheral) modes, can depend on pmic for
1341 * vbus notifications
Steve Muckle9161d302010-02-11 11:50:40 -08001342 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001343 if ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2)
1344 && (machine_is_msm8x60_surf() ||
1345 pmic_id_notif_supported)) {
1346 if (init)
1347 ret = msm_charger_register_vbus_sn(callback);
1348 else {
1349 msm_charger_unregister_vbus_sn(callback);
1350 ret = 0;
1351 }
1352 } else {
1353#if !defined(CONFIG_USB_EHCI_MSM_72K)
1354 if (init)
1355 ret = msm_charger_register_vbus_sn(callback);
1356 else {
1357 msm_charger_unregister_vbus_sn(callback);
1358 ret = 0;
1359 }
1360#endif
1361 }
1362 return ret;
1363}
1364#endif
1365
1366#if defined(CONFIG_USB_GADGET_MSM_72K) || defined(CONFIG_USB_EHCI_MSM_72K)
1367static struct msm_otg_platform_data msm_otg_pdata = {
1368 /* if usb link is in sps there is no need for
1369 * usb pclk as dayatona fabric clock will be
1370 * used instead
1371 */
1372 .pclk_src_name = "dfab_usb_hs_clk",
1373 .pemp_level = PRE_EMPHASIS_WITH_20_PERCENT,
1374 .cdr_autoreset = CDR_AUTO_RESET_DISABLE,
1375 .se1_gating = SE1_GATING_DISABLE,
Chandra Devireddyb3fc78c2011-08-30 17:25:55 +05301376 .bam_disable = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001377#ifdef CONFIG_USB_EHCI_MSM_72K
1378 .pmic_id_notif_init = msm_hsusb_pmic_id_notif_init,
1379#endif
1380#ifdef CONFIG_USB_EHCI_MSM_72K
1381 .vbus_power = msm_hsusb_vbus_power,
1382#endif
1383#ifdef CONFIG_BATTERY_MSM8X60
1384 .pmic_vbus_notif_init = msm_hsusb_pmic_vbus_notif_init,
1385#endif
1386 .ldo_init = msm_hsusb_ldo_init,
1387 .ldo_enable = msm_hsusb_ldo_enable,
1388 .config_vddcx = msm_hsusb_config_vddcx,
1389 .init_vddcx = msm_hsusb_init_vddcx,
1390#ifdef CONFIG_BATTERY_MSM8X60
1391 .chg_vbus_draw = msm_charger_vbus_draw,
1392#endif
1393};
1394#endif
1395
1396#ifdef CONFIG_USB_GADGET_MSM_72K
1397static struct msm_hsusb_gadget_platform_data msm_gadget_pdata = {
1398 .is_phy_status_timer_on = 1,
1399};
1400#endif
1401
1402#ifdef CONFIG_USB_G_ANDROID
1403
1404#define PID_MAGIC_ID 0x71432909
1405#define SERIAL_NUM_MAGIC_ID 0x61945374
1406#define SERIAL_NUMBER_LENGTH 127
1407#define DLOAD_USB_BASE_ADD 0x2A05F0C8
1408
1409struct magic_num_struct {
1410 uint32_t pid;
1411 uint32_t serial_num;
1412};
1413
1414struct dload_struct {
1415 uint32_t reserved1;
1416 uint32_t reserved2;
1417 uint32_t reserved3;
1418 uint16_t reserved4;
1419 uint16_t pid;
1420 char serial_number[SERIAL_NUMBER_LENGTH];
1421 uint16_t reserved5;
1422 struct magic_num_struct
1423 magic_struct;
1424};
1425
1426static int usb_diag_update_pid_and_serial_num(uint32_t pid, const char *snum)
1427{
1428 struct dload_struct __iomem *dload = 0;
1429
1430 dload = ioremap(DLOAD_USB_BASE_ADD, sizeof(*dload));
1431 if (!dload) {
1432 pr_err("%s: cannot remap I/O memory region: %08x\n",
1433 __func__, DLOAD_USB_BASE_ADD);
1434 return -ENXIO;
1435 }
1436
1437 pr_debug("%s: dload:%p pid:%x serial_num:%s\n",
1438 __func__, dload, pid, snum);
1439 /* update pid */
1440 dload->magic_struct.pid = PID_MAGIC_ID;
1441 dload->pid = pid;
1442
1443 /* update serial number */
1444 dload->magic_struct.serial_num = 0;
1445 if (!snum)
1446 return 0;
1447
1448 dload->magic_struct.serial_num = SERIAL_NUM_MAGIC_ID;
1449 strncpy(dload->serial_number, snum, SERIAL_NUMBER_LENGTH);
1450 dload->serial_number[SERIAL_NUMBER_LENGTH - 1] = '\0';
1451
1452 iounmap(dload);
1453
1454 return 0;
1455}
1456
1457static struct android_usb_platform_data android_usb_pdata = {
1458 .update_pid_and_serial_num = usb_diag_update_pid_and_serial_num,
1459};
1460
1461static struct platform_device android_usb_device = {
1462 .name = "android_usb",
1463 .id = -1,
1464 .dev = {
1465 .platform_data = &android_usb_pdata,
1466 },
1467};
1468
1469
1470#endif
1471
1472#ifdef CONFIG_MSM_VPE
1473static struct resource msm_vpe_resources[] = {
1474 {
1475 .start = 0x05300000,
1476 .end = 0x05300000 + SZ_1M - 1,
1477 .flags = IORESOURCE_MEM,
1478 },
1479 {
1480 .start = INT_VPE,
1481 .end = INT_VPE,
1482 .flags = IORESOURCE_IRQ,
1483 },
1484};
1485
1486static struct platform_device msm_vpe_device = {
1487 .name = "msm_vpe",
1488 .id = 0,
1489 .num_resources = ARRAY_SIZE(msm_vpe_resources),
1490 .resource = msm_vpe_resources,
1491};
1492#endif
1493
1494#ifdef CONFIG_MSM_CAMERA
1495#ifdef CONFIG_MSM_CAMERA_FLASH
1496#define VFE_CAMIF_TIMER1_GPIO 29
1497#define VFE_CAMIF_TIMER2_GPIO 30
1498#define VFE_CAMIF_TIMER3_GPIO_INT 31
1499#define FUSION_VFE_CAMIF_TIMER1_GPIO 42
1500static struct msm_camera_sensor_flash_src msm_flash_src = {
1501 .flash_sr_type = MSM_CAMERA_FLASH_SRC_PMIC,
1502 ._fsrc.pmic_src.num_of_src = 2,
1503 ._fsrc.pmic_src.low_current = 100,
1504 ._fsrc.pmic_src.high_current = 300,
1505 ._fsrc.pmic_src.led_src_1 = PMIC8058_ID_FLASH_LED_0,
1506 ._fsrc.pmic_src.led_src_2 = PMIC8058_ID_FLASH_LED_1,
1507 ._fsrc.pmic_src.pmic_set_current = pm8058_set_flash_led_current,
1508};
1509#ifdef CONFIG_IMX074
1510static struct msm_camera_sensor_strobe_flash_data strobe_flash_xenon = {
1511 .flash_trigger = VFE_CAMIF_TIMER2_GPIO,
1512 .flash_charge = VFE_CAMIF_TIMER1_GPIO,
1513 .flash_charge_done = VFE_CAMIF_TIMER3_GPIO_INT,
1514 .flash_recharge_duration = 50000,
1515 .irq = MSM_GPIO_TO_INT(VFE_CAMIF_TIMER3_GPIO_INT),
1516};
1517#endif
1518#endif
1519
1520int msm_cam_gpio_tbl[] = {
1521 32,/*CAMIF_MCLK*/
1522 47,/*CAMIF_I2C_DATA*/
1523 48,/*CAMIF_I2C_CLK*/
1524 105,/*STANDBY*/
1525};
1526
1527enum msm_cam_stat{
1528 MSM_CAM_OFF,
1529 MSM_CAM_ON,
1530};
1531
1532static int config_gpio_table(enum msm_cam_stat stat)
1533{
1534 int rc = 0, i = 0;
1535 if (stat == MSM_CAM_ON) {
1536 for (i = 0; i < ARRAY_SIZE(msm_cam_gpio_tbl); i++) {
1537 rc = gpio_request(msm_cam_gpio_tbl[i], "CAM_GPIO");
1538 if (unlikely(rc < 0)) {
1539 pr_err("%s not able to get gpio\n", __func__);
1540 for (i--; i >= 0; i--)
1541 gpio_free(msm_cam_gpio_tbl[i]);
1542 break;
1543 }
1544 }
1545 } else {
1546 for (i = 0; i < ARRAY_SIZE(msm_cam_gpio_tbl); i++)
1547 gpio_free(msm_cam_gpio_tbl[i]);
1548 }
1549 return rc;
1550}
1551
1552static struct msm_camera_sensor_platform_info sensor_board_info = {
1553 .mount_angle = 0
1554};
1555
1556/*external regulator VREG_5V*/
1557static struct regulator *reg_flash_5V;
1558
1559static int config_camera_on_gpios_fluid(void)
1560{
1561 int rc = 0;
1562
1563 reg_flash_5V = regulator_get(NULL, "8901_mpp0");
1564 if (IS_ERR(reg_flash_5V)) {
1565 pr_err("'%s' regulator not found, rc=%ld\n",
1566 "8901_mpp0", IS_ERR(reg_flash_5V));
1567 return -ENODEV;
1568 }
1569
1570 rc = regulator_enable(reg_flash_5V);
1571 if (rc) {
1572 pr_err("'%s' regulator enable failed, rc=%d\n",
1573 "8901_mpp0", rc);
1574 regulator_put(reg_flash_5V);
1575 return rc;
1576 }
1577
1578#ifdef CONFIG_IMX074
1579 sensor_board_info.mount_angle = 90;
1580#endif
1581 rc = config_gpio_table(MSM_CAM_ON);
1582 if (rc < 0) {
1583 printk(KERN_ERR "%s: CAMSENSOR gpio table request"
1584 "failed\n", __func__);
1585 return rc;
1586 }
1587
1588 rc = gpio_request(GPIO_EXT_CAMIF_PWR_EN, "CAM_EN");
1589 if (rc < 0) {
1590 printk(KERN_ERR "%s: CAMSENSOR gpio %d request"
1591 "failed\n", __func__, GPIO_EXT_CAMIF_PWR_EN);
1592 regulator_disable(reg_flash_5V);
1593 regulator_put(reg_flash_5V);
1594 return rc;
1595 }
1596 gpio_direction_output(GPIO_EXT_CAMIF_PWR_EN, 0);
1597 msleep(20);
1598 gpio_set_value_cansleep(GPIO_EXT_CAMIF_PWR_EN, 1);
1599
1600
1601 /*Enable LED_FLASH_EN*/
1602 rc = gpio_request(GPIO_LED_FLASH_EN, "LED_FLASH_EN");
1603 if (rc < 0) {
1604 printk(KERN_ERR "%s: CAMSENSOR gpio %d request"
1605 "failed\n", __func__, GPIO_LED_FLASH_EN);
1606
1607 regulator_disable(reg_flash_5V);
1608 regulator_put(reg_flash_5V);
1609 config_gpio_table(MSM_CAM_OFF);
1610 gpio_set_value_cansleep(GPIO_EXT_CAMIF_PWR_EN, 0);
1611 gpio_free(GPIO_EXT_CAMIF_PWR_EN);
1612 return rc;
1613 }
1614 gpio_direction_output(GPIO_LED_FLASH_EN, 1);
1615 msleep(20);
1616 return rc;
1617}
1618
1619
1620static void config_camera_off_gpios_fluid(void)
1621{
1622 regulator_disable(reg_flash_5V);
1623 regulator_put(reg_flash_5V);
1624
1625 gpio_direction_output(GPIO_LED_FLASH_EN, 0);
1626 gpio_free(GPIO_LED_FLASH_EN);
1627
1628 config_gpio_table(MSM_CAM_OFF);
1629
1630 gpio_set_value_cansleep(GPIO_EXT_CAMIF_PWR_EN, 0);
1631 gpio_free(GPIO_EXT_CAMIF_PWR_EN);
1632}
1633static int config_camera_on_gpios(void)
1634{
1635 int rc = 0;
1636
1637 if (machine_is_msm8x60_fluid())
1638 return config_camera_on_gpios_fluid();
1639
1640 rc = config_gpio_table(MSM_CAM_ON);
1641 if (rc < 0) {
1642 printk(KERN_ERR "%s: CAMSENSOR gpio table request"
1643 "failed\n", __func__);
1644 return rc;
1645 }
1646
Jilai Wang971f97f2011-07-13 14:25:25 -04001647 if (!machine_is_msm8x60_dragon()) {
1648 rc = gpio_request(GPIO_EXT_CAMIF_PWR_EN, "CAM_EN");
1649 if (rc < 0) {
1650 config_gpio_table(MSM_CAM_OFF);
1651 pr_err("%s: CAMSENSOR gpio %d request"
1652 "failed\n", __func__, GPIO_EXT_CAMIF_PWR_EN);
1653 return rc;
1654 }
1655 gpio_direction_output(GPIO_EXT_CAMIF_PWR_EN, 0);
1656 msleep(20);
1657 gpio_set_value_cansleep(GPIO_EXT_CAMIF_PWR_EN, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001658 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001659
1660#ifdef CONFIG_MSM_CAMERA_FLASH
1661#ifdef CONFIG_IMX074
1662 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
1663 strobe_flash_xenon.flash_charge = FUSION_VFE_CAMIF_TIMER1_GPIO;
1664#endif
1665#endif
1666 return rc;
1667}
1668
1669static void config_camera_off_gpios(void)
1670{
1671 if (machine_is_msm8x60_fluid())
1672 return config_camera_off_gpios_fluid();
1673
1674
1675 config_gpio_table(MSM_CAM_OFF);
1676
Jilai Wang971f97f2011-07-13 14:25:25 -04001677 if (!machine_is_msm8x60_dragon()) {
1678 gpio_set_value_cansleep(GPIO_EXT_CAMIF_PWR_EN, 0);
1679 gpio_free(GPIO_EXT_CAMIF_PWR_EN);
1680 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001681}
1682
1683#ifdef CONFIG_QS_S5K4E1
1684
1685#define QS_CAM_HC37_CAM_PD PM8058_GPIO_PM_TO_SYS(26)
1686
1687static int config_camera_on_gpios_qs_cam_fluid(void)
1688{
1689 int rc = 0;
1690
1691 /* request QS_CAM_HC37_CAM_PD as an output to HC37 ASIC pin CAM_PD */
1692 rc = gpio_request(QS_CAM_HC37_CAM_PD, "QS_CAM_HC37_CAM_PD");
1693 if (rc < 0) {
1694 printk(KERN_ERR "%s: QS_CAM_HC37_CAM_PD gpio %d request"
1695 " failed\n", __func__, QS_CAM_HC37_CAM_PD);
1696 return rc;
1697 }
1698 gpio_direction_output(QS_CAM_HC37_CAM_PD, 0);
1699 msleep(20);
1700 gpio_set_value_cansleep(QS_CAM_HC37_CAM_PD, 1);
1701 msleep(20);
1702
1703 /*
1704 * Set GPIO_AUX_CAM_2P7_EN to 1 on North Expander IO2
1705 * to enable 2.7V power to Camera
1706 */
1707 rc = gpio_request(GPIO_AUX_CAM_2P7_EN, "CAM_2P7_EN");
1708 if (rc < 0) {
1709 printk(KERN_ERR "%s: CAMSENSOR gpio %d request"
1710 " failed\n", __func__, GPIO_AUX_CAM_2P7_EN);
1711 gpio_set_value_cansleep(QS_CAM_HC37_CAM_PD, 0);
1712 gpio_free(QS_CAM_HC37_CAM_PD);
1713 return rc;
1714 }
1715 gpio_direction_output(GPIO_AUX_CAM_2P7_EN, 0);
1716 msleep(20);
1717 gpio_set_value_cansleep(GPIO_AUX_CAM_2P7_EN, 1);
1718 msleep(20);
1719
1720 rc = config_camera_on_gpios_fluid();
1721 if (rc < 0) {
1722 printk(KERN_ERR "%s: config_camera_on_gpios_fluid"
1723 " failed\n", __func__);
1724 gpio_set_value_cansleep(QS_CAM_HC37_CAM_PD, 0);
1725 gpio_free(QS_CAM_HC37_CAM_PD);
1726 gpio_set_value_cansleep(GPIO_AUX_CAM_2P7_EN, 0);
1727 gpio_free(GPIO_AUX_CAM_2P7_EN);
1728 return rc;
1729 }
1730 return rc;
1731}
1732
1733static void config_camera_off_gpios_qs_cam_fluid(void)
1734{
1735 /*
1736 * Set GPIO_AUX_CAM_2P7_EN to 0 on North Expander IO2
1737 * to disable 2.7V power to Camera
1738 */
1739 gpio_set_value_cansleep(GPIO_AUX_CAM_2P7_EN, 0);
1740 gpio_free(GPIO_AUX_CAM_2P7_EN);
1741
1742 /* set QS_CAM_HC37_CAM_PD to 0 to power off HC37 ASIC*/
1743 gpio_set_value_cansleep(QS_CAM_HC37_CAM_PD, 0);
1744 gpio_free(QS_CAM_HC37_CAM_PD);
1745
1746 config_camera_off_gpios_fluid();
1747 return;
1748}
1749
1750static int config_camera_on_gpios_qs_cam(void)
1751{
1752 int rc = 0;
1753
1754 if (machine_is_msm8x60_fluid())
1755 return config_camera_on_gpios_qs_cam_fluid();
1756
1757 rc = config_camera_on_gpios();
1758 return rc;
1759}
1760
1761static void config_camera_off_gpios_qs_cam(void)
1762{
1763 if (machine_is_msm8x60_fluid())
1764 return config_camera_off_gpios_qs_cam_fluid();
1765
1766 config_camera_off_gpios();
1767 return;
1768}
1769#endif
1770
1771static int config_camera_on_gpios_web_cam(void)
1772{
1773 int rc = 0;
1774 rc = config_gpio_table(MSM_CAM_ON);
1775 if (rc < 0) {
1776 printk(KERN_ERR "%s: CAMSENSOR gpio table request"
1777 "failed\n", __func__);
1778 return rc;
1779 }
1780
Jilai Wang53d27a82011-07-13 14:32:58 -04001781 if (!(machine_is_msm8x60_fluid() || machine_is_msm8x60_dragon())) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001782 rc = gpio_request(GPIO_WEB_CAMIF_STANDBY, "CAM_EN");
1783 if (rc < 0) {
1784 config_gpio_table(MSM_CAM_OFF);
1785 pr_err(KERN_ERR "%s: CAMSENSOR gpio %d request"
1786 "failed\n", __func__, GPIO_WEB_CAMIF_STANDBY);
1787 return rc;
1788 }
1789 gpio_direction_output(GPIO_WEB_CAMIF_STANDBY, 0);
1790 }
1791 return rc;
1792}
1793
1794static void config_camera_off_gpios_web_cam(void)
1795{
1796 config_gpio_table(MSM_CAM_OFF);
Jilai Wang53d27a82011-07-13 14:32:58 -04001797 if (!(machine_is_msm8x60_fluid() || machine_is_msm8x60_dragon())) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001798 gpio_set_value_cansleep(GPIO_WEB_CAMIF_STANDBY, 1);
1799 gpio_free(GPIO_WEB_CAMIF_STANDBY);
1800 }
1801 return;
1802}
1803
1804#ifdef CONFIG_MSM_BUS_SCALING
1805static struct msm_bus_vectors cam_init_vectors[] = {
1806 {
1807 .src = MSM_BUS_MASTER_VFE,
1808 .dst = MSM_BUS_SLAVE_SMI,
1809 .ab = 0,
1810 .ib = 0,
1811 },
1812 {
1813 .src = MSM_BUS_MASTER_VFE,
1814 .dst = MSM_BUS_SLAVE_EBI_CH0,
1815 .ab = 0,
1816 .ib = 0,
1817 },
1818 {
1819 .src = MSM_BUS_MASTER_VPE,
1820 .dst = MSM_BUS_SLAVE_SMI,
1821 .ab = 0,
1822 .ib = 0,
1823 },
1824 {
1825 .src = MSM_BUS_MASTER_VPE,
1826 .dst = MSM_BUS_SLAVE_EBI_CH0,
1827 .ab = 0,
1828 .ib = 0,
1829 },
1830 {
1831 .src = MSM_BUS_MASTER_JPEG_ENC,
1832 .dst = MSM_BUS_SLAVE_SMI,
1833 .ab = 0,
1834 .ib = 0,
1835 },
1836 {
1837 .src = MSM_BUS_MASTER_JPEG_ENC,
1838 .dst = MSM_BUS_SLAVE_EBI_CH0,
1839 .ab = 0,
1840 .ib = 0,
1841 },
1842};
1843
1844static struct msm_bus_vectors cam_preview_vectors[] = {
1845 {
1846 .src = MSM_BUS_MASTER_VFE,
1847 .dst = MSM_BUS_SLAVE_SMI,
1848 .ab = 0,
1849 .ib = 0,
1850 },
1851 {
1852 .src = MSM_BUS_MASTER_VFE,
1853 .dst = MSM_BUS_SLAVE_EBI_CH0,
1854 .ab = 283115520,
1855 .ib = 452984832,
1856 },
1857 {
1858 .src = MSM_BUS_MASTER_VPE,
1859 .dst = MSM_BUS_SLAVE_SMI,
1860 .ab = 0,
1861 .ib = 0,
1862 },
1863 {
1864 .src = MSM_BUS_MASTER_VPE,
1865 .dst = MSM_BUS_SLAVE_EBI_CH0,
1866 .ab = 0,
1867 .ib = 0,
1868 },
1869 {
1870 .src = MSM_BUS_MASTER_JPEG_ENC,
1871 .dst = MSM_BUS_SLAVE_SMI,
1872 .ab = 0,
1873 .ib = 0,
1874 },
1875 {
1876 .src = MSM_BUS_MASTER_JPEG_ENC,
1877 .dst = MSM_BUS_SLAVE_EBI_CH0,
1878 .ab = 0,
1879 .ib = 0,
1880 },
1881};
1882
1883static struct msm_bus_vectors cam_video_vectors[] = {
1884 {
1885 .src = MSM_BUS_MASTER_VFE,
1886 .dst = MSM_BUS_SLAVE_SMI,
1887 .ab = 283115520,
1888 .ib = 452984832,
1889 },
1890 {
1891 .src = MSM_BUS_MASTER_VFE,
1892 .dst = MSM_BUS_SLAVE_EBI_CH0,
1893 .ab = 283115520,
1894 .ib = 452984832,
1895 },
1896 {
1897 .src = MSM_BUS_MASTER_VPE,
1898 .dst = MSM_BUS_SLAVE_SMI,
1899 .ab = 319610880,
1900 .ib = 511377408,
1901 },
1902 {
1903 .src = MSM_BUS_MASTER_VPE,
1904 .dst = MSM_BUS_SLAVE_EBI_CH0,
1905 .ab = 0,
1906 .ib = 0,
1907 },
1908 {
1909 .src = MSM_BUS_MASTER_JPEG_ENC,
1910 .dst = MSM_BUS_SLAVE_SMI,
1911 .ab = 0,
1912 .ib = 0,
1913 },
1914 {
1915 .src = MSM_BUS_MASTER_JPEG_ENC,
1916 .dst = MSM_BUS_SLAVE_EBI_CH0,
1917 .ab = 0,
1918 .ib = 0,
1919 },
1920};
1921
1922static struct msm_bus_vectors cam_snapshot_vectors[] = {
1923 {
1924 .src = MSM_BUS_MASTER_VFE,
1925 .dst = MSM_BUS_SLAVE_SMI,
1926 .ab = 566231040,
1927 .ib = 905969664,
1928 },
1929 {
1930 .src = MSM_BUS_MASTER_VFE,
1931 .dst = MSM_BUS_SLAVE_EBI_CH0,
1932 .ab = 69984000,
1933 .ib = 111974400,
1934 },
1935 {
1936 .src = MSM_BUS_MASTER_VPE,
1937 .dst = MSM_BUS_SLAVE_SMI,
1938 .ab = 0,
1939 .ib = 0,
1940 },
1941 {
1942 .src = MSM_BUS_MASTER_VPE,
1943 .dst = MSM_BUS_SLAVE_EBI_CH0,
1944 .ab = 0,
1945 .ib = 0,
1946 },
1947 {
1948 .src = MSM_BUS_MASTER_JPEG_ENC,
1949 .dst = MSM_BUS_SLAVE_SMI,
1950 .ab = 320864256,
1951 .ib = 513382810,
1952 },
1953 {
1954 .src = MSM_BUS_MASTER_JPEG_ENC,
1955 .dst = MSM_BUS_SLAVE_EBI_CH0,
1956 .ab = 320864256,
1957 .ib = 513382810,
1958 },
1959};
1960
1961static struct msm_bus_vectors cam_zsl_vectors[] = {
1962 {
1963 .src = MSM_BUS_MASTER_VFE,
1964 .dst = MSM_BUS_SLAVE_SMI,
1965 .ab = 566231040,
1966 .ib = 905969664,
1967 },
1968 {
1969 .src = MSM_BUS_MASTER_VFE,
1970 .dst = MSM_BUS_SLAVE_EBI_CH0,
1971 .ab = 706199040,
1972 .ib = 1129918464,
1973 },
1974 {
1975 .src = MSM_BUS_MASTER_VPE,
1976 .dst = MSM_BUS_SLAVE_SMI,
1977 .ab = 0,
1978 .ib = 0,
1979 },
1980 {
1981 .src = MSM_BUS_MASTER_VPE,
1982 .dst = MSM_BUS_SLAVE_EBI_CH0,
1983 .ab = 0,
1984 .ib = 0,
1985 },
1986 {
1987 .src = MSM_BUS_MASTER_JPEG_ENC,
1988 .dst = MSM_BUS_SLAVE_SMI,
1989 .ab = 320864256,
1990 .ib = 513382810,
1991 },
1992 {
1993 .src = MSM_BUS_MASTER_JPEG_ENC,
1994 .dst = MSM_BUS_SLAVE_EBI_CH0,
1995 .ab = 320864256,
1996 .ib = 513382810,
1997 },
1998};
1999
2000static struct msm_bus_vectors cam_stereo_video_vectors[] = {
2001 {
2002 .src = MSM_BUS_MASTER_VFE,
2003 .dst = MSM_BUS_SLAVE_SMI,
2004 .ab = 212336640,
2005 .ib = 339738624,
2006 },
2007 {
2008 .src = MSM_BUS_MASTER_VFE,
2009 .dst = MSM_BUS_SLAVE_EBI_CH0,
2010 .ab = 25090560,
2011 .ib = 40144896,
2012 },
2013 {
2014 .src = MSM_BUS_MASTER_VPE,
2015 .dst = MSM_BUS_SLAVE_SMI,
2016 .ab = 239708160,
2017 .ib = 383533056,
2018 },
2019 {
2020 .src = MSM_BUS_MASTER_VPE,
2021 .dst = MSM_BUS_SLAVE_EBI_CH0,
2022 .ab = 79902720,
2023 .ib = 127844352,
2024 },
2025 {
2026 .src = MSM_BUS_MASTER_JPEG_ENC,
2027 .dst = MSM_BUS_SLAVE_SMI,
2028 .ab = 0,
2029 .ib = 0,
2030 },
2031 {
2032 .src = MSM_BUS_MASTER_JPEG_ENC,
2033 .dst = MSM_BUS_SLAVE_EBI_CH0,
2034 .ab = 0,
2035 .ib = 0,
2036 },
2037};
2038
2039static struct msm_bus_vectors cam_stereo_snapshot_vectors[] = {
2040 {
2041 .src = MSM_BUS_MASTER_VFE,
2042 .dst = MSM_BUS_SLAVE_SMI,
2043 .ab = 0,
2044 .ib = 0,
2045 },
2046 {
2047 .src = MSM_BUS_MASTER_VFE,
2048 .dst = MSM_BUS_SLAVE_EBI_CH0,
2049 .ab = 300902400,
2050 .ib = 481443840,
2051 },
2052 {
2053 .src = MSM_BUS_MASTER_VPE,
2054 .dst = MSM_BUS_SLAVE_SMI,
2055 .ab = 230307840,
2056 .ib = 368492544,
2057 },
2058 {
2059 .src = MSM_BUS_MASTER_VPE,
2060 .dst = MSM_BUS_SLAVE_EBI_CH0,
2061 .ab = 245113344,
2062 .ib = 392181351,
2063 },
2064 {
2065 .src = MSM_BUS_MASTER_JPEG_ENC,
2066 .dst = MSM_BUS_SLAVE_SMI,
2067 .ab = 106536960,
2068 .ib = 170459136,
2069 },
2070 {
2071 .src = MSM_BUS_MASTER_JPEG_ENC,
2072 .dst = MSM_BUS_SLAVE_EBI_CH0,
2073 .ab = 106536960,
2074 .ib = 170459136,
2075 },
2076};
2077
2078static struct msm_bus_paths cam_bus_client_config[] = {
2079 {
2080 ARRAY_SIZE(cam_init_vectors),
2081 cam_init_vectors,
2082 },
2083 {
2084 ARRAY_SIZE(cam_preview_vectors),
2085 cam_preview_vectors,
2086 },
2087 {
2088 ARRAY_SIZE(cam_video_vectors),
2089 cam_video_vectors,
2090 },
2091 {
2092 ARRAY_SIZE(cam_snapshot_vectors),
2093 cam_snapshot_vectors,
2094 },
2095 {
2096 ARRAY_SIZE(cam_zsl_vectors),
2097 cam_zsl_vectors,
2098 },
2099 {
2100 ARRAY_SIZE(cam_stereo_video_vectors),
2101 cam_stereo_video_vectors,
2102 },
2103 {
2104 ARRAY_SIZE(cam_stereo_snapshot_vectors),
2105 cam_stereo_snapshot_vectors,
2106 },
2107};
2108
2109static struct msm_bus_scale_pdata cam_bus_client_pdata = {
2110 cam_bus_client_config,
2111 ARRAY_SIZE(cam_bus_client_config),
2112 .name = "msm_camera",
2113};
2114#endif
2115
2116struct msm_camera_device_platform_data msm_camera_device_data = {
2117 .camera_gpio_on = config_camera_on_gpios,
2118 .camera_gpio_off = config_camera_off_gpios,
2119 .ioext.csiphy = 0x04800000,
2120 .ioext.csisz = 0x00000400,
2121 .ioext.csiirq = CSI_0_IRQ,
2122 .ioclk.mclk_clk_rate = 24000000,
2123 .ioclk.vfe_clk_rate = 228570000,
2124#ifdef CONFIG_MSM_BUS_SCALING
2125 .cam_bus_scale_table = &cam_bus_client_pdata,
2126#endif
2127};
2128
2129#ifdef CONFIG_QS_S5K4E1
2130struct msm_camera_device_platform_data msm_camera_device_data_qs_cam = {
2131 .camera_gpio_on = config_camera_on_gpios_qs_cam,
2132 .camera_gpio_off = config_camera_off_gpios_qs_cam,
2133 .ioext.csiphy = 0x04800000,
2134 .ioext.csisz = 0x00000400,
2135 .ioext.csiirq = CSI_0_IRQ,
2136 .ioclk.mclk_clk_rate = 24000000,
2137 .ioclk.vfe_clk_rate = 228570000,
2138#ifdef CONFIG_MSM_BUS_SCALING
2139 .cam_bus_scale_table = &cam_bus_client_pdata,
2140#endif
2141};
2142#endif
2143
2144struct msm_camera_device_platform_data msm_camera_device_data_web_cam = {
2145 .camera_gpio_on = config_camera_on_gpios_web_cam,
2146 .camera_gpio_off = config_camera_off_gpios_web_cam,
2147 .ioext.csiphy = 0x04900000,
2148 .ioext.csisz = 0x00000400,
2149 .ioext.csiirq = CSI_1_IRQ,
2150 .ioclk.mclk_clk_rate = 24000000,
2151 .ioclk.vfe_clk_rate = 228570000,
2152#ifdef CONFIG_MSM_BUS_SCALING
2153 .cam_bus_scale_table = &cam_bus_client_pdata,
2154#endif
2155};
2156
2157struct resource msm_camera_resources[] = {
2158 {
2159 .start = 0x04500000,
2160 .end = 0x04500000 + SZ_1M - 1,
2161 .flags = IORESOURCE_MEM,
2162 },
2163 {
2164 .start = VFE_IRQ,
2165 .end = VFE_IRQ,
2166 .flags = IORESOURCE_IRQ,
2167 },
2168};
2169#ifdef CONFIG_MT9E013
2170static struct msm_camera_sensor_platform_info mt9e013_sensor_8660_info = {
2171 .mount_angle = 0
2172};
2173
2174static struct msm_camera_sensor_flash_data flash_mt9e013 = {
2175 .flash_type = MSM_CAMERA_FLASH_LED,
2176 .flash_src = &msm_flash_src
2177};
2178
2179static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
2180 .sensor_name = "mt9e013",
2181 .sensor_reset = 106,
2182 .sensor_pwd = 85,
2183 .vcm_pwd = 1,
2184 .vcm_enable = 0,
2185 .pdata = &msm_camera_device_data,
2186 .resource = msm_camera_resources,
2187 .num_resources = ARRAY_SIZE(msm_camera_resources),
2188 .flash_data = &flash_mt9e013,
2189 .strobe_flash_data = &strobe_flash_xenon,
2190 .sensor_platform_info = &mt9e013_sensor_8660_info,
2191 .csi_if = 1
2192};
2193struct platform_device msm_camera_sensor_mt9e013 = {
2194 .name = "msm_camera_mt9e013",
2195 .dev = {
2196 .platform_data = &msm_camera_sensor_mt9e013_data,
2197 },
2198};
2199#endif
2200
2201#ifdef CONFIG_IMX074
2202static struct msm_camera_sensor_flash_data flash_imx074 = {
2203 .flash_type = MSM_CAMERA_FLASH_LED,
2204 .flash_src = &msm_flash_src
2205};
2206
2207static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
2208 .sensor_name = "imx074",
2209 .sensor_reset = 106,
2210 .sensor_pwd = 85,
2211 .vcm_pwd = GPIO_AUX_CAM_2P7_EN,
2212 .vcm_enable = 1,
2213 .pdata = &msm_camera_device_data,
2214 .resource = msm_camera_resources,
2215 .num_resources = ARRAY_SIZE(msm_camera_resources),
2216 .flash_data = &flash_imx074,
2217 .strobe_flash_data = &strobe_flash_xenon,
2218 .sensor_platform_info = &sensor_board_info,
2219 .csi_if = 1
2220};
2221struct platform_device msm_camera_sensor_imx074 = {
2222 .name = "msm_camera_imx074",
2223 .dev = {
2224 .platform_data = &msm_camera_sensor_imx074_data,
2225 },
2226};
2227#endif
2228#ifdef CONFIG_WEBCAM_OV9726
2229
2230static struct msm_camera_sensor_platform_info ov9726_sensor_8660_info = {
2231 .mount_angle = 0
2232};
2233
2234static struct msm_camera_sensor_flash_data flash_ov9726 = {
2235 .flash_type = MSM_CAMERA_FLASH_LED,
2236 .flash_src = &msm_flash_src
2237};
2238static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
2239 .sensor_name = "ov9726",
Kevin Chan3382c512011-07-19 21:00:45 -07002240 .sensor_reset_enable = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002241 .sensor_reset = GPIO_FRONT_CAM_RESET_N,
2242 .sensor_pwd = 85,
2243 .vcm_pwd = 1,
2244 .vcm_enable = 0,
2245 .pdata = &msm_camera_device_data_web_cam,
2246 .resource = msm_camera_resources,
2247 .num_resources = ARRAY_SIZE(msm_camera_resources),
2248 .flash_data = &flash_ov9726,
2249 .sensor_platform_info = &ov9726_sensor_8660_info,
2250 .csi_if = 1
2251};
2252struct platform_device msm_camera_sensor_webcam_ov9726 = {
2253 .name = "msm_camera_ov9726",
2254 .dev = {
2255 .platform_data = &msm_camera_sensor_ov9726_data,
2256 },
2257};
2258#endif
2259#ifdef CONFIG_WEBCAM_OV7692
2260static struct msm_camera_sensor_flash_data flash_ov7692 = {
2261 .flash_type = MSM_CAMERA_FLASH_LED,
2262 .flash_src = &msm_flash_src
2263};
2264static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
2265 .sensor_name = "ov7692",
2266 .sensor_reset = GPIO_WEB_CAMIF_RESET_N,
2267 .sensor_pwd = 85,
2268 .vcm_pwd = 1,
2269 .vcm_enable = 0,
2270 .pdata = &msm_camera_device_data_web_cam,
2271 .resource = msm_camera_resources,
2272 .num_resources = ARRAY_SIZE(msm_camera_resources),
2273 .flash_data = &flash_ov7692,
2274 .csi_if = 1
2275};
2276
2277static struct platform_device msm_camera_sensor_webcam_ov7692 = {
2278 .name = "msm_camera_ov7692",
2279 .dev = {
2280 .platform_data = &msm_camera_sensor_ov7692_data,
2281 },
2282};
2283#endif
Jilai Wang971f97f2011-07-13 14:25:25 -04002284#ifdef CONFIG_VX6953
2285static struct msm_camera_sensor_platform_info vx6953_sensor_8660_info = {
2286 .mount_angle = 270
2287};
2288
2289static struct msm_camera_sensor_flash_data flash_vx6953 = {
2290 .flash_type = MSM_CAMERA_FLASH_NONE,
2291 .flash_src = &msm_flash_src
2292};
2293
2294static struct msm_camera_sensor_info msm_camera_sensor_vx6953_data = {
2295 .sensor_name = "vx6953",
2296 .sensor_reset = 63,
2297 .sensor_pwd = 63,
2298 .vcm_pwd = GPIO_AUX_CAM_2P7_EN,
2299 .vcm_enable = 1,
2300 .pdata = &msm_camera_device_data,
2301 .resource = msm_camera_resources,
2302 .num_resources = ARRAY_SIZE(msm_camera_resources),
2303 .flash_data = &flash_vx6953,
2304 .sensor_platform_info = &vx6953_sensor_8660_info,
2305 .csi_if = 1
2306};
2307struct platform_device msm_camera_sensor_vx6953 = {
2308 .name = "msm_camera_vx6953",
2309 .dev = {
2310 .platform_data = &msm_camera_sensor_vx6953_data,
2311 },
2312};
2313#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002314#ifdef CONFIG_QS_S5K4E1
2315
Nishant Pandit613ab7a2011-09-02 03:36:01 +05302316static struct msm_camera_sensor_platform_info qs_s5k4e1_sensor_8660_info = {
2317#ifdef CONFIG_FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
2318 .mount_angle = 90
2319#else
2320 .mount_angle = 0
2321#endif
2322};
2323
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002324static char eeprom_data[864];
2325static struct msm_camera_sensor_flash_data flash_qs_s5k4e1 = {
2326 .flash_type = MSM_CAMERA_FLASH_LED,
2327 .flash_src = &msm_flash_src
2328};
2329
2330static struct msm_camera_sensor_info msm_camera_sensor_qs_s5k4e1_data = {
2331 .sensor_name = "qs_s5k4e1",
2332 .sensor_reset = 106,
2333 .sensor_pwd = 85,
2334 .vcm_pwd = 1,
2335 .vcm_enable = 0,
2336 .pdata = &msm_camera_device_data_qs_cam,
2337 .resource = msm_camera_resources,
2338 .num_resources = ARRAY_SIZE(msm_camera_resources),
2339 .flash_data = &flash_qs_s5k4e1,
2340 .strobe_flash_data = &strobe_flash_xenon,
Nishant Pandit613ab7a2011-09-02 03:36:01 +05302341 .sensor_platform_info = &qs_s5k4e1_sensor_8660_info,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002342 .csi_if = 1,
2343 .eeprom_data = eeprom_data,
2344};
2345struct platform_device msm_camera_sensor_qs_s5k4e1 = {
2346 .name = "msm_camera_qs_s5k4e1",
2347 .dev = {
2348 .platform_data = &msm_camera_sensor_qs_s5k4e1_data,
2349 },
2350};
2351#endif
2352static struct i2c_board_info msm_camera_boardinfo[] __initdata = {
2353 #ifdef CONFIG_MT9E013
2354 {
2355 I2C_BOARD_INFO("mt9e013", 0x6C >> 2),
2356 },
2357 #endif
2358 #ifdef CONFIG_IMX074
2359 {
2360 I2C_BOARD_INFO("imx074", 0x1A),
2361 },
2362 #endif
2363 #ifdef CONFIG_WEBCAM_OV7692
2364 {
2365 I2C_BOARD_INFO("ov7692", 0x78),
2366 },
2367 #endif
2368 #ifdef CONFIG_WEBCAM_OV9726
2369 {
2370 I2C_BOARD_INFO("ov9726", 0x10),
2371 },
2372 #endif
2373 #ifdef CONFIG_QS_S5K4E1
2374 {
2375 I2C_BOARD_INFO("qs_s5k4e1", 0x20),
2376 },
2377 #endif
2378};
Jilai Wang971f97f2011-07-13 14:25:25 -04002379
2380static struct i2c_board_info msm_camera_dragon_boardinfo[] __initdata = {
Jilai Wang53d27a82011-07-13 14:32:58 -04002381 #ifdef CONFIG_WEBCAM_OV9726
2382 {
2383 I2C_BOARD_INFO("ov9726", 0x10),
2384 },
2385 #endif
Jilai Wang971f97f2011-07-13 14:25:25 -04002386 #ifdef CONFIG_VX6953
2387 {
2388 I2C_BOARD_INFO("vx6953", 0x20),
2389 },
2390 #endif
2391};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002392#endif
2393
2394#ifdef CONFIG_MSM_GEMINI
2395static struct resource msm_gemini_resources[] = {
2396 {
2397 .start = 0x04600000,
2398 .end = 0x04600000 + SZ_1M - 1,
2399 .flags = IORESOURCE_MEM,
2400 },
2401 {
2402 .start = INT_JPEG,
2403 .end = INT_JPEG,
2404 .flags = IORESOURCE_IRQ,
2405 },
2406};
2407
2408static struct platform_device msm_gemini_device = {
2409 .name = "msm_gemini",
2410 .resource = msm_gemini_resources,
2411 .num_resources = ARRAY_SIZE(msm_gemini_resources),
2412};
2413#endif
2414
2415#ifdef CONFIG_I2C_QUP
2416static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
2417{
2418}
2419
2420static struct msm_i2c_platform_data msm_gsbi3_qup_i2c_pdata = {
2421 .clk_freq = 384000,
2422 .src_clk_rate = 24000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002423 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
2424};
2425
2426static struct msm_i2c_platform_data msm_gsbi4_qup_i2c_pdata = {
2427 .clk_freq = 100000,
2428 .src_clk_rate = 24000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002429 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
2430};
2431
2432static struct msm_i2c_platform_data msm_gsbi7_qup_i2c_pdata = {
2433 .clk_freq = 100000,
2434 .src_clk_rate = 24000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002435 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
2436};
2437
2438static struct msm_i2c_platform_data msm_gsbi8_qup_i2c_pdata = {
2439 .clk_freq = 100000,
2440 .src_clk_rate = 24000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002441 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
2442};
2443
2444static struct msm_i2c_platform_data msm_gsbi9_qup_i2c_pdata = {
2445 .clk_freq = 100000,
2446 .src_clk_rate = 24000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002447 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
2448};
2449
2450static struct msm_i2c_platform_data msm_gsbi12_qup_i2c_pdata = {
2451 .clk_freq = 100000,
2452 .src_clk_rate = 24000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002453 .use_gsbi_shared_mode = 1,
2454 .msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
2455};
2456#endif
2457
2458#if defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
2459static struct msm_spi_platform_data msm_gsbi1_qup_spi_pdata = {
2460 .max_clock_speed = 24000000,
2461};
2462
2463static struct msm_spi_platform_data msm_gsbi10_qup_spi_pdata = {
2464 .max_clock_speed = 24000000,
2465};
2466#endif
2467
2468#ifdef CONFIG_I2C_SSBI
2469/* PMIC SSBI */
2470static struct msm_i2c_ssbi_platform_data msm_ssbi1_pdata = {
2471 .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
2472};
2473
2474/* PMIC SSBI */
2475static struct msm_i2c_ssbi_platform_data msm_ssbi2_pdata = {
2476 .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
2477};
2478
2479/* CODEC/TSSC SSBI */
2480static struct msm_i2c_ssbi_platform_data msm_ssbi3_pdata = {
2481 .controller_type = MSM_SBI_CTRL_SSBI,
2482};
2483#endif
2484
2485#ifdef CONFIG_BATTERY_MSM
2486/* Use basic value for fake MSM battery */
2487static struct msm_psy_batt_pdata msm_psy_batt_data = {
2488 .avail_chg_sources = AC_CHG,
2489};
2490
2491static struct platform_device msm_batt_device = {
2492 .name = "msm-battery",
2493 .id = -1,
2494 .dev.platform_data = &msm_psy_batt_data,
2495};
2496#endif
2497
2498#ifdef CONFIG_FB_MSM_LCDC_DSUB
2499/* VGA = 1440 x 900 x 4(bpp) x 2(pages)
2500 prim = 1024 x 600 x 4(bpp) x 2(pages)
2501 This is the difference. */
2502#define MSM_FB_DSUB_PMEM_ADDER (0xA32000-0x4B0000)
2503#else
2504#define MSM_FB_DSUB_PMEM_ADDER (0)
2505#endif
2506
2507/* Sensors DSPS platform data */
2508#ifdef CONFIG_MSM_DSPS
2509
2510static struct dsps_gpio_info dsps_surf_gpios[] = {
2511 {
2512 .name = "compass_rst_n",
2513 .num = GPIO_COMPASS_RST_N,
2514 .on_val = 1, /* device not in reset */
2515 .off_val = 0, /* device in reset */
2516 },
2517 {
2518 .name = "gpio_r_altimeter_reset_n",
2519 .num = GPIO_R_ALTIMETER_RESET_N,
2520 .on_val = 1, /* device not in reset */
2521 .off_val = 0, /* device in reset */
2522 }
2523};
2524
2525static struct dsps_gpio_info dsps_fluid_gpios[] = {
2526 {
2527 .name = "gpio_n_altimeter_reset_n",
2528 .num = GPIO_N_ALTIMETER_RESET_N,
2529 .on_val = 1, /* device not in reset */
2530 .off_val = 0, /* device in reset */
2531 }
2532};
2533
2534static void __init msm8x60_init_dsps(void)
2535{
2536 struct msm_dsps_platform_data *pdata =
2537 msm_dsps_device.dev.platform_data;
2538 /*
2539 * On Fluid the Compass sensor Chip-Select (CS) is directly connected
2540 * to the power supply and not controled via GPIOs. Fluid uses a
2541 * different IO-Expender (north) than used on surf/ffa.
2542 */
2543 if (machine_is_msm8x60_fluid()) {
2544 /* fluid has different firmware, gpios */
2545 peripheral_dsps.name = DSPS_PIL_FLUID_NAME;
2546 pdata->pil_name = DSPS_PIL_FLUID_NAME;
2547 pdata->gpios = dsps_fluid_gpios;
2548 pdata->gpios_num = ARRAY_SIZE(dsps_fluid_gpios);
2549 } else {
2550 peripheral_dsps.name = DSPS_PIL_GENERIC_NAME;
2551 pdata->pil_name = DSPS_PIL_GENERIC_NAME;
2552 pdata->gpios = dsps_surf_gpios;
2553 pdata->gpios_num = ARRAY_SIZE(dsps_surf_gpios);
2554 }
2555
2556 msm_pil_add_device(&peripheral_dsps);
2557
2558 platform_device_register(&msm_dsps_device);
2559}
2560#endif /* CONFIG_MSM_DSPS */
2561
2562#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
2563/* prim = 1024 x 600 x 4(bpp) x 3(pages) */
2564#define MSM_FB_PRIM_BUF_SIZE 0x708000
2565#else
2566/* prim = 1024 x 600 x 4(bpp) x 2(pages) */
2567#define MSM_FB_PRIM_BUF_SIZE 0x4B0000
2568#endif
2569
2570
2571#ifdef CONFIG_FB_MSM_OVERLAY_WRITEBACK
kuogee hsieha39040b2011-08-11 15:40:45 -07002572/* width x height x 3 bpp x 2 frame buffer */
2573#define MSM_FB_WRITEBACK_SIZE (1024 * 600 * 3 * 2)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002574#else
2575#define MSM_FB_WRITEBACK_SIZE 0
2576#endif
2577
2578#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
2579/* prim = 1024 x 600 x 4(bpp) x 2(pages)
2580 * hdmi = 1920 x 1080 x 2(bpp) x 1(page)
2581 * Note: must be multiple of 4096 */
2582#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + 0x3F4800 + \
2583 MSM_FB_WRITEBACK_SIZE + MSM_FB_DSUB_PMEM_ADDER, 4096)
2584#elif defined(CONFIG_FB_MSM_TVOUT)
2585/* prim = 1024 x 600 x 4(bpp) x 2(pages)
2586 * tvout = 720 x 576 x 2(bpp) x 2(pages)
2587 * Note: must be multiple of 4096 */
2588#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + 0x195000 + \
2589 MSM_FB_WRITEBACK_SIZE + MSM_FB_DSUB_PMEM_ADDER, 4096)
2590#else /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
2591#define MSM_FB_SIZE roundup(MSM_FB_PRIM_BUF_SIZE + \
2592 MSM_FB_WRITEBACK_SIZE + MSM_FB_DSUB_PMEM_ADDER, 4096)
2593#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
2594
2595#define MSM_PMEM_SF_SIZE 0x4000000 /* 64 Mbytes */
2596
2597#define MSM_PMEM_KERNEL_EBI1_SIZE 0x600000
2598#define MSM_PMEM_ADSP_SIZE 0x2000000
Ben Romberger09e462d2011-08-09 15:24:37 -07002599#define MSM_PMEM_AUDIO_SIZE 0x28B000
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002600
2601#define MSM_SMI_BASE 0x38000000
2602#define MSM_SMI_SIZE 0x4000000
2603
2604#define KERNEL_SMI_BASE (MSM_SMI_BASE)
2605#define KERNEL_SMI_SIZE 0x300000
2606
2607#define USER_SMI_BASE (KERNEL_SMI_BASE + KERNEL_SMI_SIZE)
2608#define USER_SMI_SIZE (MSM_SMI_SIZE - KERNEL_SMI_SIZE)
2609#define MSM_PMEM_SMIPOOL_SIZE USER_SMI_SIZE
2610
2611static unsigned fb_size;
2612static int __init fb_size_setup(char *p)
2613{
2614 fb_size = memparse(p, NULL);
2615 return 0;
2616}
2617early_param("fb_size", fb_size_setup);
2618
2619static unsigned pmem_kernel_ebi1_size = MSM_PMEM_KERNEL_EBI1_SIZE;
2620static int __init pmem_kernel_ebi1_size_setup(char *p)
2621{
2622 pmem_kernel_ebi1_size = memparse(p, NULL);
2623 return 0;
2624}
2625early_param("pmem_kernel_ebi1_size", pmem_kernel_ebi1_size_setup);
2626
2627#ifdef CONFIG_ANDROID_PMEM
2628static unsigned pmem_sf_size = MSM_PMEM_SF_SIZE;
2629static int __init pmem_sf_size_setup(char *p)
2630{
2631 pmem_sf_size = memparse(p, NULL);
2632 return 0;
2633}
2634early_param("pmem_sf_size", pmem_sf_size_setup);
2635
2636static unsigned pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
2637
2638static int __init pmem_adsp_size_setup(char *p)
2639{
2640 pmem_adsp_size = memparse(p, NULL);
2641 return 0;
2642}
2643early_param("pmem_adsp_size", pmem_adsp_size_setup);
2644
2645static unsigned pmem_audio_size = MSM_PMEM_AUDIO_SIZE;
2646
2647static int __init pmem_audio_size_setup(char *p)
2648{
2649 pmem_audio_size = memparse(p, NULL);
2650 return 0;
2651}
2652early_param("pmem_audio_size", pmem_audio_size_setup);
2653#endif
2654
2655static struct resource msm_fb_resources[] = {
2656 {
2657 .flags = IORESOURCE_DMA,
2658 }
2659};
2660
2661#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
2662static int msm_fb_detect_panel(const char *name)
2663{
2664 if (machine_is_msm8x60_fluid()) {
2665 uint32_t soc_platform_version = socinfo_get_platform_version();
2666 if (SOCINFO_VERSION_MAJOR(soc_platform_version) < 3) {
2667#ifdef CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT
2668 if (!strncmp(name, LCDC_SAMSUNG_OLED_PANEL_NAME,
2669 strlen(LCDC_SAMSUNG_OLED_PANEL_NAME)))
2670 return 0;
2671#endif
2672 } else { /*P3 and up use AUO panel */
2673#ifdef CONFIG_FB_MSM_LCDC_AUO_WVGA
2674 if (!strncmp(name, LCDC_AUO_PANEL_NAME,
2675 strlen(LCDC_AUO_PANEL_NAME)))
2676 return 0;
2677#endif
2678 }
2679 if (!strncmp(name, LCDC_SAMSUNG_WSVGA_PANEL_NAME,
2680 strlen(LCDC_SAMSUNG_WSVGA_PANEL_NAME)))
2681 return -ENODEV;
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -04002682#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
2683 } else if machine_is_msm8x60_dragon() {
2684 if (!strncmp(name, LCDC_NT35582_PANEL_NAME,
2685 sizeof(LCDC_NT35582_PANEL_NAME) - 1))
2686 return 0;
2687#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002688 } else {
2689 if (!strncmp(name, LCDC_SAMSUNG_WSVGA_PANEL_NAME,
2690 strlen(LCDC_SAMSUNG_WSVGA_PANEL_NAME)))
2691 return 0;
2692 if (!strncmp(name, LCDC_SAMSUNG_OLED_PANEL_NAME,
2693 strlen(LCDC_SAMSUNG_OLED_PANEL_NAME)))
2694 return -ENODEV;
2695 }
2696 pr_warning("%s: not supported '%s'", __func__, name);
2697 return -ENODEV;
2698}
2699
2700static struct msm_fb_platform_data msm_fb_pdata = {
2701 .detect_client = msm_fb_detect_panel,
2702};
2703#endif /* CONFIG_FB_MSM_LCDC_AUTO_DETECT */
2704
2705static struct platform_device msm_fb_device = {
2706 .name = "msm_fb",
2707 .id = 0,
2708 .num_resources = ARRAY_SIZE(msm_fb_resources),
2709 .resource = msm_fb_resources,
2710#ifdef CONFIG_FB_MSM_LCDC_AUTO_DETECT
2711 .dev.platform_data = &msm_fb_pdata,
2712#endif /* CONFIG_FB_MSM_LCDC_AUTO_DETECT */
2713};
2714
2715#ifdef CONFIG_ANDROID_PMEM
2716static struct android_pmem_platform_data android_pmem_pdata = {
2717 .name = "pmem",
2718 .allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
2719 .cached = 1,
2720 .memory_type = MEMTYPE_EBI1,
2721};
2722
2723static struct platform_device android_pmem_device = {
2724 .name = "android_pmem",
2725 .id = 0,
2726 .dev = {.platform_data = &android_pmem_pdata},
2727};
2728
2729static struct android_pmem_platform_data android_pmem_adsp_pdata = {
2730 .name = "pmem_adsp",
2731 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2732 .cached = 0,
2733 .memory_type = MEMTYPE_EBI1,
2734};
2735
2736static struct platform_device android_pmem_adsp_device = {
2737 .name = "android_pmem",
2738 .id = 2,
2739 .dev = { .platform_data = &android_pmem_adsp_pdata },
2740};
2741
2742static struct android_pmem_platform_data android_pmem_audio_pdata = {
2743 .name = "pmem_audio",
2744 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2745 .cached = 0,
2746 .memory_type = MEMTYPE_EBI1,
2747};
2748
2749static struct platform_device android_pmem_audio_device = {
2750 .name = "android_pmem",
2751 .id = 4,
2752 .dev = { .platform_data = &android_pmem_audio_pdata },
2753};
2754
Laura Abbott1e36a022011-06-22 17:08:13 -07002755#define PMEM_BUS_WIDTH(_bw) \
2756 { \
2757 .vectors = &(struct msm_bus_vectors){ \
2758 .src = MSM_BUS_MASTER_AMPSS_M0, \
2759 .dst = MSM_BUS_SLAVE_SMI, \
2760 .ib = (_bw), \
2761 .ab = 0, \
2762 }, \
2763 .num_paths = 1, \
2764 }
2765static struct msm_bus_paths pmem_smi_table[] = {
2766 [0] = PMEM_BUS_WIDTH(0), /* Off */
2767 [1] = PMEM_BUS_WIDTH(1), /* On */
2768};
2769
2770static struct msm_bus_scale_pdata smi_client_pdata = {
2771 .usecase = pmem_smi_table,
2772 .num_usecases = ARRAY_SIZE(pmem_smi_table),
2773 .name = "pmem_smi",
2774};
2775
2776void pmem_request_smi_region(void *data)
2777{
2778 int bus_id = (int) data;
2779
2780 msm_bus_scale_client_update_request(bus_id, 1);
2781}
2782
2783void pmem_release_smi_region(void *data)
2784{
2785 int bus_id = (int) data;
2786
2787 msm_bus_scale_client_update_request(bus_id, 0);
2788}
2789
2790void *pmem_setup_smi_region(void)
2791{
2792 return (void *)msm_bus_scale_register_client(&smi_client_pdata);
2793}
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002794static struct android_pmem_platform_data android_pmem_smipool_pdata = {
2795 .name = "pmem_smipool",
2796 .allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
2797 .cached = 0,
2798 .memory_type = MEMTYPE_SMI,
Laura Abbott1e36a022011-06-22 17:08:13 -07002799 .request_region = pmem_request_smi_region,
2800 .release_region = pmem_release_smi_region,
2801 .setup_region = pmem_setup_smi_region,
2802 .map_on_demand = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002803};
2804static struct platform_device android_pmem_smipool_device = {
2805 .name = "android_pmem",
2806 .id = 7,
2807 .dev = { .platform_data = &android_pmem_smipool_pdata },
2808};
2809
2810#endif
2811
2812#define GPIO_DONGLE_PWR_EN 258
2813static void setup_display_power(void);
2814static int lcdc_vga_enabled;
2815static int vga_enable_request(int enable)
2816{
2817 if (enable)
2818 lcdc_vga_enabled = 1;
2819 else
2820 lcdc_vga_enabled = 0;
2821 setup_display_power();
2822
2823 return 0;
2824}
2825
2826#define GPIO_BACKLIGHT_PWM0 0
2827#define GPIO_BACKLIGHT_PWM1 1
2828
2829static int pmic_backlight_gpio[2]
2830 = { GPIO_BACKLIGHT_PWM0, GPIO_BACKLIGHT_PWM1 };
2831static struct msm_panel_common_pdata lcdc_samsung_panel_data = {
2832 .gpio_num = pmic_backlight_gpio, /* two LPG CHANNELS for backlight */
2833 .vga_switch = vga_enable_request,
2834};
2835
2836static struct platform_device lcdc_samsung_panel_device = {
2837 .name = LCDC_SAMSUNG_WSVGA_PANEL_NAME,
2838 .id = 0,
2839 .dev = {
2840 .platform_data = &lcdc_samsung_panel_data,
2841 }
2842};
2843#if (!defined(CONFIG_SPI_QUP)) && \
2844 (defined(CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT) || \
2845 defined(CONFIG_FB_MSM_LCDC_AUO_WVGA))
2846
2847static int lcdc_spi_gpio_array_num[] = {
2848 LCDC_SPI_GPIO_CLK,
2849 LCDC_SPI_GPIO_CS,
2850 LCDC_SPI_GPIO_MOSI,
2851};
2852
2853static uint32_t lcdc_spi_gpio_config_data[] = {
2854 GPIO_CFG(LCDC_SPI_GPIO_CLK, 0,
2855 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2856 GPIO_CFG(LCDC_SPI_GPIO_CS, 0,
2857 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2858 GPIO_CFG(LCDC_SPI_GPIO_MOSI, 0,
2859 GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
2860};
2861
2862static void lcdc_config_spi_gpios(int enable)
2863{
2864 int n;
2865 for (n = 0; n < ARRAY_SIZE(lcdc_spi_gpio_config_data); ++n)
2866 gpio_tlmm_config(lcdc_spi_gpio_config_data[n], 0);
2867}
2868#endif
2869
2870#ifdef CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT
2871#ifdef CONFIG_SPI_QUP
2872static struct spi_board_info lcdc_samsung_spi_board_info[] __initdata = {
2873 {
2874 .modalias = LCDC_SAMSUNG_SPI_DEVICE_NAME,
2875 .mode = SPI_MODE_3,
2876 .bus_num = 1,
2877 .chip_select = 0,
2878 .max_speed_hz = 10800000,
2879 }
2880};
2881#endif /* CONFIG_SPI_QUP */
2882
2883static struct msm_panel_common_pdata lcdc_samsung_oled_panel_data = {
2884#ifndef CONFIG_SPI_QUP
2885 .panel_config_gpio = lcdc_config_spi_gpios,
2886 .gpio_num = lcdc_spi_gpio_array_num,
2887#endif
2888};
2889
2890static struct platform_device lcdc_samsung_oled_panel_device = {
2891 .name = LCDC_SAMSUNG_OLED_PANEL_NAME,
2892 .id = 0,
2893 .dev.platform_data = &lcdc_samsung_oled_panel_data,
2894};
2895#endif /*CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT */
2896
2897#ifdef CONFIG_FB_MSM_LCDC_AUO_WVGA
2898#ifdef CONFIG_SPI_QUP
2899static struct spi_board_info lcdc_auo_spi_board_info[] __initdata = {
2900 {
2901 .modalias = LCDC_AUO_SPI_DEVICE_NAME,
2902 .mode = SPI_MODE_3,
2903 .bus_num = 1,
2904 .chip_select = 0,
2905 .max_speed_hz = 10800000,
2906 }
2907};
2908#endif
2909
2910static struct msm_panel_common_pdata lcdc_auo_wvga_panel_data = {
2911#ifndef CONFIG_SPI_QUP
2912 .panel_config_gpio = lcdc_config_spi_gpios,
2913 .gpio_num = lcdc_spi_gpio_array_num,
2914#endif
2915};
2916
2917static struct platform_device lcdc_auo_wvga_panel_device = {
2918 .name = LCDC_AUO_PANEL_NAME,
2919 .id = 0,
2920 .dev.platform_data = &lcdc_auo_wvga_panel_data,
2921};
2922#endif /*CONFIG_FB_MSM_LCDC_AUO_WVGA*/
2923
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -04002924#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
2925
2926#define GPIO_NT35582_RESET 94
2927#define GPIO_NT35582_BL_EN_HW_PIN 24
2928#define GPIO_NT35582_BL_EN \
2929 PM8058_GPIO_PM_TO_SYS(GPIO_NT35582_BL_EN_HW_PIN - 1)
2930
2931static int lcdc_nt35582_pmic_gpio[] = {GPIO_NT35582_BL_EN };
2932
2933static struct msm_panel_common_pdata lcdc_nt35582_panel_data = {
2934 .gpio_num = lcdc_nt35582_pmic_gpio,
2935};
2936
2937static struct platform_device lcdc_nt35582_panel_device = {
2938 .name = LCDC_NT35582_PANEL_NAME,
2939 .id = 0,
2940 .dev = {
2941 .platform_data = &lcdc_nt35582_panel_data,
2942 }
2943};
2944
2945static struct spi_board_info lcdc_nt35582_spi_board_info[] __initdata = {
2946 {
2947 .modalias = "lcdc_nt35582_spi",
2948 .mode = SPI_MODE_0,
2949 .bus_num = 0,
2950 .chip_select = 0,
2951 .max_speed_hz = 1100000,
2952 }
2953};
2954#endif
2955
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002956#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
2957static struct resource hdmi_msm_resources[] = {
2958 {
2959 .name = "hdmi_msm_qfprom_addr",
2960 .start = 0x00700000,
2961 .end = 0x007060FF,
2962 .flags = IORESOURCE_MEM,
2963 },
2964 {
2965 .name = "hdmi_msm_hdmi_addr",
2966 .start = 0x04A00000,
2967 .end = 0x04A00FFF,
2968 .flags = IORESOURCE_MEM,
2969 },
2970 {
2971 .name = "hdmi_msm_irq",
2972 .start = HDMI_IRQ,
2973 .end = HDMI_IRQ,
2974 .flags = IORESOURCE_IRQ,
2975 },
2976};
2977
2978static int hdmi_enable_5v(int on);
2979static int hdmi_core_power(int on, int show);
2980static int hdmi_cec_power(int on);
2981
2982static struct msm_hdmi_platform_data hdmi_msm_data = {
2983 .irq = HDMI_IRQ,
2984 .enable_5v = hdmi_enable_5v,
2985 .core_power = hdmi_core_power,
2986 .cec_power = hdmi_cec_power,
2987};
2988
2989static struct platform_device hdmi_msm_device = {
2990 .name = "hdmi_msm",
2991 .id = 0,
2992 .num_resources = ARRAY_SIZE(hdmi_msm_resources),
2993 .resource = hdmi_msm_resources,
2994 .dev.platform_data = &hdmi_msm_data,
2995};
2996#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
2997
2998#ifdef CONFIG_FB_MSM_MIPI_DSI
2999static struct platform_device mipi_dsi_toshiba_panel_device = {
3000 .name = "mipi_toshiba",
3001 .id = 0,
3002};
3003
3004#define FPGA_3D_GPIO_CONFIG_ADDR 0x1D00017A
3005
Nagamalleswararao Ganjieac5dfa2011-07-23 17:31:16 -07003006static struct mipi_dsi_panel_platform_data novatek_pdata = {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003007 .fpga_3d_config_addr = FPGA_3D_GPIO_CONFIG_ADDR,
3008};
3009
3010static struct platform_device mipi_dsi_novatek_panel_device = {
3011 .name = "mipi_novatek",
3012 .id = 0,
3013 .dev = {
3014 .platform_data = &novatek_pdata,
3015 }
3016};
3017#endif
3018
3019static void __init msm8x60_allocate_memory_regions(void)
3020{
3021 void *addr;
3022 unsigned long size;
3023
3024 size = MSM_FB_SIZE;
3025 addr = alloc_bootmem_align(size, 0x1000);
3026 msm_fb_resources[0].start = __pa(addr);
3027 msm_fb_resources[0].end = msm_fb_resources[0].start + size - 1;
3028 pr_info("allocating %lu bytes at %p (%lx physical) for fb\n",
3029 size, addr, __pa(addr));
3030
3031}
3032
3033#if defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C) || \
3034 defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C_MODULE)
3035/*virtual key support */
3036static ssize_t tma300_vkeys_show(struct kobject *kobj,
3037 struct kobj_attribute *attr, char *buf)
3038{
3039 return sprintf(buf,
3040 __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":60:900:90:120"
3041 ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":180:900:90:120"
3042 ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":300:900:90:120"
3043 ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":420:900:90:120"
3044 "\n");
3045}
3046
3047static struct kobj_attribute tma300_vkeys_attr = {
3048 .attr = {
3049 .mode = S_IRUGO,
3050 },
3051 .show = &tma300_vkeys_show,
3052};
3053
3054static struct attribute *tma300_properties_attrs[] = {
3055 &tma300_vkeys_attr.attr,
3056 NULL
3057};
3058
3059static struct attribute_group tma300_properties_attr_group = {
3060 .attrs = tma300_properties_attrs,
3061};
3062
3063static struct kobject *properties_kobj;
3064
3065
3066
3067#define CYTTSP_TS_GPIO_IRQ 61
3068static int cyttsp_platform_init(struct i2c_client *client)
3069{
3070 int rc = -EINVAL;
3071 struct regulator *pm8058_l5 = NULL, *pm8058_s3;
3072
3073 if (machine_is_msm8x60_fluid()) {
3074 pm8058_l5 = regulator_get(NULL, "8058_l5");
3075 if (IS_ERR(pm8058_l5)) {
3076 pr_err("%s: regulator get of 8058_l5 failed (%ld)\n",
3077 __func__, PTR_ERR(pm8058_l5));
3078 rc = PTR_ERR(pm8058_l5);
3079 return rc;
3080 }
3081 rc = regulator_set_voltage(pm8058_l5, 2850000, 2850000);
3082 if (rc) {
3083 pr_err("%s: regulator_set_voltage of 8058_l5 failed(%d)\n",
3084 __func__, rc);
3085 goto reg_l5_put;
3086 }
3087
3088 rc = regulator_enable(pm8058_l5);
3089 if (rc) {
3090 pr_err("%s: regulator_enable of 8058_l5 failed(%d)\n",
3091 __func__, rc);
3092 goto reg_l5_put;
3093 }
3094 }
3095 /* vote for s3 to enable i2c communication lines */
3096 pm8058_s3 = regulator_get(NULL, "8058_s3");
3097 if (IS_ERR(pm8058_s3)) {
3098 pr_err("%s: regulator get of 8058_s3 failed (%ld)\n",
3099 __func__, PTR_ERR(pm8058_s3));
3100 rc = PTR_ERR(pm8058_s3);
3101 goto reg_l5_disable;
3102 }
3103
3104 rc = regulator_set_voltage(pm8058_s3, 1800000, 1800000);
3105 if (rc) {
3106 pr_err("%s: regulator_set_voltage() = %d\n",
3107 __func__, rc);
3108 goto reg_s3_put;
3109 }
3110
3111 rc = regulator_enable(pm8058_s3);
3112 if (rc) {
3113 pr_err("%s: regulator_enable of 8058_l5 failed(%d)\n",
3114 __func__, rc);
3115 goto reg_s3_put;
3116 }
3117
3118 /* wait for vregs to stabilize */
3119 usleep_range(10000, 10000);
3120
3121 /* check this device active by reading first byte/register */
3122 rc = i2c_smbus_read_byte_data(client, 0x01);
3123 if (rc < 0) {
3124 pr_err("%s: i2c sanity check failed\n", __func__);
3125 goto reg_s3_disable;
3126 }
3127
3128 /* virtual keys */
3129 if (machine_is_msm8x60_fluid()) {
3130 tma300_vkeys_attr.attr.name = "virtualkeys.cyttsp-i2c";
3131 properties_kobj = kobject_create_and_add("board_properties",
3132 NULL);
3133 if (properties_kobj)
3134 rc = sysfs_create_group(properties_kobj,
3135 &tma300_properties_attr_group);
3136 if (!properties_kobj || rc)
3137 pr_err("%s: failed to create board_properties\n",
3138 __func__);
3139 }
3140 return CY_OK;
3141
3142reg_s3_disable:
3143 regulator_disable(pm8058_s3);
3144reg_s3_put:
3145 regulator_put(pm8058_s3);
3146reg_l5_disable:
3147 if (machine_is_msm8x60_fluid())
3148 regulator_disable(pm8058_l5);
3149reg_l5_put:
3150 if (machine_is_msm8x60_fluid())
3151 regulator_put(pm8058_l5);
3152 return rc;
3153}
3154
3155static int cyttsp_platform_resume(struct i2c_client *client)
3156{
3157 /* add any special code to strobe a wakeup pin or chip reset */
3158 msleep(10);
3159
3160 return CY_OK;
3161}
3162
3163static struct cyttsp_platform_data cyttsp_fluid_pdata = {
3164 .flags = 0x04,
3165 .gen = CY_GEN3, /* or */
3166 .use_st = CY_USE_ST,
3167 .use_mt = CY_USE_MT,
3168 .use_hndshk = CY_SEND_HNDSHK,
3169 .use_trk_id = CY_USE_TRACKING_ID,
Anirudh Ghayal15187772011-06-22 17:39:41 +05303170 .use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003171 .use_gestures = CY_USE_GESTURES,
3172 /* activate up to 4 groups
3173 * and set active distance
3174 */
3175 .gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 |
3176 CY_GEST_GRP3 | CY_GEST_GRP4 |
3177 CY_ACT_DIST,
3178 /* change act_intrvl to customize the Active power state
3179 * scanning/processing refresh interval for Operating mode
3180 */
3181 .act_intrvl = CY_ACT_INTRVL_DFLT,
3182 /* change tch_tmout to customize the touch timeout for the
3183 * Active power state for Operating mode
3184 */
3185 .tch_tmout = CY_TCH_TMOUT_DFLT,
3186 /* change lp_intrvl to customize the Low Power power state
3187 * scanning/processing refresh interval for Operating mode
3188 */
3189 .lp_intrvl = CY_LP_INTRVL_DFLT,
3190 .sleep_gpio = -1,
3191 .resout_gpio = -1,
3192 .irq_gpio = CYTTSP_TS_GPIO_IRQ,
3193 .resume = cyttsp_platform_resume,
3194 .init = cyttsp_platform_init,
3195};
3196
3197static struct cyttsp_platform_data cyttsp_tmg240_pdata = {
3198 .panel_maxx = 1083,
3199 .panel_maxy = 659,
3200 .disp_minx = 30,
3201 .disp_maxx = 1053,
3202 .disp_miny = 30,
3203 .disp_maxy = 629,
3204 .correct_fw_ver = 8,
3205 .fw_fname = "cyttsp_8660_ffa.hex",
3206 .flags = 0x00,
3207 .gen = CY_GEN2, /* or */
3208 .use_st = CY_USE_ST,
3209 .use_mt = CY_USE_MT,
3210 .use_hndshk = CY_SEND_HNDSHK,
3211 .use_trk_id = CY_USE_TRACKING_ID,
Anirudh Ghayal15187772011-06-22 17:39:41 +05303212 .use_sleep = CY_USE_DEEP_SLEEP_SEL | CY_USE_LOW_POWER_SEL,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003213 .use_gestures = CY_USE_GESTURES,
3214 /* activate up to 4 groups
3215 * and set active distance
3216 */
3217 .gest_set = CY_GEST_GRP1 | CY_GEST_GRP2 |
3218 CY_GEST_GRP3 | CY_GEST_GRP4 |
3219 CY_ACT_DIST,
3220 /* change act_intrvl to customize the Active power state
3221 * scanning/processing refresh interval for Operating mode
3222 */
3223 .act_intrvl = CY_ACT_INTRVL_DFLT,
3224 /* change tch_tmout to customize the touch timeout for the
3225 * Active power state for Operating mode
3226 */
3227 .tch_tmout = CY_TCH_TMOUT_DFLT,
3228 /* change lp_intrvl to customize the Low Power power state
3229 * scanning/processing refresh interval for Operating mode
3230 */
3231 .lp_intrvl = CY_LP_INTRVL_DFLT,
3232 .sleep_gpio = -1,
3233 .resout_gpio = -1,
3234 .irq_gpio = CYTTSP_TS_GPIO_IRQ,
3235 .resume = cyttsp_platform_resume,
3236 .init = cyttsp_platform_init,
Mohan Pallaka1ea7d8a2011-08-18 15:06:00 +05303237 .disable_ghost_det = true,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003238};
3239static void cyttsp_set_params(void)
3240{
3241 if (SOCINFO_VERSION_MAJOR(socinfo_get_platform_version()) < 3) {
3242 cyttsp_fluid_pdata.fw_fname = "cyttsp_8660_fluid_p2.hex";
3243 cyttsp_fluid_pdata.panel_maxx = 539;
3244 cyttsp_fluid_pdata.panel_maxy = 994;
3245 cyttsp_fluid_pdata.disp_minx = 30;
3246 cyttsp_fluid_pdata.disp_maxx = 509;
3247 cyttsp_fluid_pdata.disp_miny = 60;
3248 cyttsp_fluid_pdata.disp_maxy = 859;
3249 cyttsp_fluid_pdata.correct_fw_ver = 4;
3250 } else {
3251 cyttsp_fluid_pdata.fw_fname = "cyttsp_8660_fluid_p3.hex";
3252 cyttsp_fluid_pdata.panel_maxx = 550;
3253 cyttsp_fluid_pdata.panel_maxy = 1013;
3254 cyttsp_fluid_pdata.disp_minx = 35;
3255 cyttsp_fluid_pdata.disp_maxx = 515;
3256 cyttsp_fluid_pdata.disp_miny = 69;
3257 cyttsp_fluid_pdata.disp_maxy = 869;
3258 cyttsp_fluid_pdata.correct_fw_ver = 5;
3259 }
3260
3261}
3262
3263static struct i2c_board_info cyttsp_fluid_info[] __initdata = {
3264 {
3265 I2C_BOARD_INFO(CY_I2C_NAME, 0x24),
3266 .platform_data = &cyttsp_fluid_pdata,
3267#ifndef CY_USE_TIMER
3268 .irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ),
3269#endif /* CY_USE_TIMER */
3270 },
3271};
3272
3273static struct i2c_board_info cyttsp_ffa_info[] __initdata = {
3274 {
3275 I2C_BOARD_INFO(CY_I2C_NAME, 0x3b),
3276 .platform_data = &cyttsp_tmg240_pdata,
3277#ifndef CY_USE_TIMER
3278 .irq = MSM_GPIO_TO_INT(CYTTSP_TS_GPIO_IRQ),
3279#endif /* CY_USE_TIMER */
3280 },
3281};
3282#endif
3283
3284static struct regulator *vreg_tmg200;
3285
3286#define TS_PEN_IRQ_GPIO 61
3287static int tmg200_power(int vreg_on)
3288{
3289 int rc = -EINVAL;
3290
3291 if (!vreg_tmg200) {
3292 printk(KERN_ERR "%s: regulator 8058_s3 not found (%d)\n",
3293 __func__, rc);
3294 return rc;
3295 }
3296
3297 rc = vreg_on ? regulator_enable(vreg_tmg200) :
3298 regulator_disable(vreg_tmg200);
3299 if (rc < 0)
3300 printk(KERN_ERR "%s: vreg 8058_s3 %s failed (%d)\n",
3301 __func__, vreg_on ? "enable" : "disable", rc);
3302
3303 /* wait for vregs to stabilize */
Amy Maloche12b5d4e2011-08-03 15:42:28 -07003304 msleep(20);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003305
3306 return rc;
3307}
3308
3309static int tmg200_dev_setup(bool enable)
3310{
3311 int rc;
3312
3313 if (enable) {
3314 vreg_tmg200 = regulator_get(NULL, "8058_s3");
3315 if (IS_ERR(vreg_tmg200)) {
3316 pr_err("%s: regulator get of 8058_s3 failed (%ld)\n",
3317 __func__, PTR_ERR(vreg_tmg200));
3318 rc = PTR_ERR(vreg_tmg200);
3319 return rc;
3320 }
3321
3322 rc = regulator_set_voltage(vreg_tmg200, 1800000, 1800000);
3323 if (rc) {
3324 pr_err("%s: regulator_set_voltage() = %d\n",
3325 __func__, rc);
3326 goto reg_put;
3327 }
3328 } else {
3329 /* put voltage sources */
3330 regulator_put(vreg_tmg200);
3331 }
3332 return 0;
3333reg_put:
3334 regulator_put(vreg_tmg200);
3335 return rc;
3336}
3337
3338static struct cy8c_ts_platform_data cy8ctmg200_pdata = {
3339 .ts_name = "msm_tmg200_ts",
3340 .dis_min_x = 0,
3341 .dis_max_x = 1023,
3342 .dis_min_y = 0,
3343 .dis_max_y = 599,
3344 .min_tid = 0,
3345 .max_tid = 255,
3346 .min_touch = 0,
3347 .max_touch = 255,
3348 .min_width = 0,
3349 .max_width = 255,
3350 .power_on = tmg200_power,
3351 .dev_setup = tmg200_dev_setup,
3352 .nfingers = 2,
3353 .irq_gpio = TS_PEN_IRQ_GPIO,
3354 .resout_gpio = GPIO_CAP_TS_RESOUT_N,
3355};
3356
3357static struct i2c_board_info cy8ctmg200_board_info[] = {
3358 {
3359 I2C_BOARD_INFO("cy8ctmg200", 0x2),
3360 .platform_data = &cy8ctmg200_pdata,
3361 }
3362};
3363
Zhang Chang Ken211df572011-07-05 19:16:39 -04003364static struct regulator *vreg_tma340;
3365
3366static int tma340_power(int vreg_on)
3367{
3368 int rc = -EINVAL;
3369
3370 if (!vreg_tma340) {
3371 pr_err("%s: regulator 8901_l2 not found (%d)\n",
3372 __func__, rc);
3373 return rc;
3374 }
3375
3376 rc = vreg_on ? regulator_enable(vreg_tma340) :
3377 regulator_disable(vreg_tma340);
3378 if (rc < 0)
3379 pr_err("%s: vreg 8901_l2 %s failed (%d)\n",
3380 __func__, vreg_on ? "enable" : "disable", rc);
3381
3382 /* wait for vregs to stabilize */
Amy Malocheb5c67e8d2011-08-18 16:39:35 -07003383 msleep(100);
Zhang Chang Ken211df572011-07-05 19:16:39 -04003384
3385 return rc;
3386}
3387
3388static struct kobject *tma340_prop_kobj;
3389
3390static int tma340_dragon_dev_setup(bool enable)
3391{
3392 int rc;
3393
3394 if (enable) {
3395 vreg_tma340 = regulator_get(NULL, "8901_l2");
3396 if (IS_ERR(vreg_tma340)) {
3397 pr_err("%s: regulator get of 8901_l2 failed (%ld)\n",
3398 __func__, PTR_ERR(vreg_tma340));
3399 rc = PTR_ERR(vreg_tma340);
3400 return rc;
3401 }
3402
3403 rc = regulator_set_voltage(vreg_tma340, 3300000, 3300000);
3404 if (rc) {
3405 pr_err("%s: regulator_set_voltage() = %d\n",
3406 __func__, rc);
3407 goto reg_put;
3408 }
3409 tma300_vkeys_attr.attr.name = "virtualkeys.cy8ctma340";
3410 tma340_prop_kobj = kobject_create_and_add("board_properties",
3411 NULL);
3412 if (tma340_prop_kobj) {
3413 rc = sysfs_create_group(tma340_prop_kobj,
3414 &tma300_properties_attr_group);
3415 if (rc) {
3416 kobject_put(tma340_prop_kobj);
3417 pr_err("%s: failed to create board_properties\n",
3418 __func__);
3419 goto reg_put;
3420 }
3421 }
3422
3423 } else {
3424 /* put voltage sources */
3425 regulator_put(vreg_tma340);
3426 /* destroy virtual keys */
3427 if (tma340_prop_kobj) {
3428 sysfs_remove_group(tma340_prop_kobj,
3429 &tma300_properties_attr_group);
3430 kobject_put(tma340_prop_kobj);
3431 }
3432 }
3433 return 0;
3434reg_put:
3435 regulator_put(vreg_tma340);
3436 return rc;
3437}
3438
3439
3440static struct cy8c_ts_platform_data cy8ctma340_dragon_pdata = {
3441 .ts_name = "cy8ctma340",
3442 .dis_min_x = 0,
3443 .dis_max_x = 479,
3444 .dis_min_y = 0,
3445 .dis_max_y = 799,
3446 .min_tid = 0,
3447 .max_tid = 255,
3448 .min_touch = 0,
3449 .max_touch = 255,
3450 .min_width = 0,
3451 .max_width = 255,
3452 .power_on = tma340_power,
3453 .dev_setup = tma340_dragon_dev_setup,
3454 .nfingers = 2,
3455 .irq_gpio = TS_PEN_IRQ_GPIO,
3456 .resout_gpio = -1,
3457};
3458
3459static struct i2c_board_info cy8ctma340_dragon_board_info[] = {
3460 {
3461 I2C_BOARD_INFO("cy8ctma340", 0x24),
3462 .platform_data = &cy8ctma340_dragon_pdata,
3463 }
3464};
3465
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003466#ifdef CONFIG_SERIAL_MSM_HS
3467static int configure_uart_gpios(int on)
3468{
3469 int ret = 0, i;
3470 int uart_gpios[] = {53, 54, 55, 56};
3471 for (i = 0; i < ARRAY_SIZE(uart_gpios); i++) {
3472 if (on) {
3473 ret = msm_gpiomux_get(uart_gpios[i]);
3474 if (unlikely(ret))
3475 break;
3476 } else {
3477 ret = msm_gpiomux_put(uart_gpios[i]);
3478 if (unlikely(ret))
3479 return ret;
3480 }
3481 }
3482 if (ret)
3483 for (; i >= 0; i--)
3484 msm_gpiomux_put(uart_gpios[i]);
3485 return ret;
3486}
3487static struct msm_serial_hs_platform_data msm_uart_dm1_pdata = {
3488 .inject_rx_on_wakeup = 1,
3489 .rx_to_inject = 0xFD,
3490 .gpio_config = configure_uart_gpios,
3491};
3492#endif
3493
3494
3495#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
3496
3497static struct gpio_led gpio_exp_leds_config[] = {
3498 {
3499 .name = "left_led1:green",
3500 .gpio = GPIO_LEFT_LED_1,
3501 .active_low = 1,
3502 .retain_state_suspended = 0,
3503 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3504 },
3505 {
3506 .name = "left_led2:red",
3507 .gpio = GPIO_LEFT_LED_2,
3508 .active_low = 1,
3509 .retain_state_suspended = 0,
3510 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3511 },
3512 {
3513 .name = "left_led3:green",
3514 .gpio = GPIO_LEFT_LED_3,
3515 .active_low = 1,
3516 .retain_state_suspended = 0,
3517 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3518 },
3519 {
3520 .name = "wlan_led:orange",
3521 .gpio = GPIO_LEFT_LED_WLAN,
3522 .active_low = 1,
3523 .retain_state_suspended = 0,
3524 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3525 },
3526 {
3527 .name = "left_led5:green",
3528 .gpio = GPIO_LEFT_LED_5,
3529 .active_low = 1,
3530 .retain_state_suspended = 0,
3531 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3532 },
3533 {
3534 .name = "right_led1:green",
3535 .gpio = GPIO_RIGHT_LED_1,
3536 .active_low = 1,
3537 .retain_state_suspended = 0,
3538 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3539 },
3540 {
3541 .name = "right_led2:red",
3542 .gpio = GPIO_RIGHT_LED_2,
3543 .active_low = 1,
3544 .retain_state_suspended = 0,
3545 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3546 },
3547 {
3548 .name = "right_led3:green",
3549 .gpio = GPIO_RIGHT_LED_3,
3550 .active_low = 1,
3551 .retain_state_suspended = 0,
3552 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3553 },
3554 {
3555 .name = "bt_led:blue",
3556 .gpio = GPIO_RIGHT_LED_BT,
3557 .active_low = 1,
3558 .retain_state_suspended = 0,
3559 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3560 },
3561 {
3562 .name = "right_led5:green",
3563 .gpio = GPIO_RIGHT_LED_5,
3564 .active_low = 1,
3565 .retain_state_suspended = 0,
3566 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3567 },
3568};
3569
3570static struct gpio_led_platform_data gpio_leds_pdata = {
3571 .num_leds = ARRAY_SIZE(gpio_exp_leds_config),
3572 .leds = gpio_exp_leds_config,
3573};
3574
3575static struct platform_device gpio_leds = {
3576 .name = "leds-gpio",
3577 .id = -1,
3578 .dev = {
3579 .platform_data = &gpio_leds_pdata,
3580 },
3581};
3582
3583static struct gpio_led fluid_gpio_leds[] = {
3584 {
3585 .name = "dual_led:green",
3586 .gpio = GPIO_LED1_GREEN_N,
3587 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3588 .active_low = 1,
3589 .retain_state_suspended = 0,
3590 },
3591 {
3592 .name = "dual_led:red",
3593 .gpio = GPIO_LED2_RED_N,
3594 .default_state = LEDS_GPIO_DEFSTATE_OFF,
3595 .active_low = 1,
3596 .retain_state_suspended = 0,
3597 },
3598};
3599
3600static struct gpio_led_platform_data gpio_led_pdata = {
3601 .leds = fluid_gpio_leds,
3602 .num_leds = ARRAY_SIZE(fluid_gpio_leds),
3603};
3604
3605static struct platform_device fluid_leds_gpio = {
3606 .name = "leds-gpio",
3607 .id = -1,
3608 .dev = {
3609 .platform_data = &gpio_led_pdata,
3610 },
3611};
3612
3613#endif
3614
3615#if defined(CONFIG_MSM_RPM_LOG) || defined(CONFIG_MSM_RPM_LOG_MODULE)
3616
3617static struct msm_rpm_log_platform_data msm_rpm_log_pdata = {
3618 .phys_addr_base = 0x00106000,
3619 .reg_offsets = {
3620 [MSM_RPM_LOG_PAGE_INDICES] = 0x00000C80,
3621 [MSM_RPM_LOG_PAGE_BUFFER] = 0x00000CA0,
3622 },
3623 .phys_size = SZ_8K,
3624 .log_len = 4096, /* log's buffer length in bytes */
3625 .log_len_mask = (4096 >> 2) - 1, /* length mask in units of u32 */
3626};
3627
3628static struct platform_device msm_rpm_log_device = {
3629 .name = "msm_rpm_log",
3630 .id = -1,
3631 .dev = {
3632 .platform_data = &msm_rpm_log_pdata,
3633 },
3634};
3635#endif
3636
3637#ifdef CONFIG_BATTERY_MSM8X60
3638static struct msm_charger_platform_data msm_charger_data = {
3639 .safety_time = 180,
3640 .update_time = 1,
3641 .max_voltage = 4200,
3642 .min_voltage = 3200,
3643};
3644
3645static struct platform_device msm_charger_device = {
3646 .name = "msm-charger",
3647 .id = -1,
3648 .dev = {
3649 .platform_data = &msm_charger_data,
3650 }
3651};
3652#endif
3653
3654/*
3655 * Consumer specific regulator names:
3656 * regulator name consumer dev_name
3657 */
3658static struct regulator_consumer_supply vreg_consumers_PM8058_L0[] = {
3659 REGULATOR_SUPPLY("8058_l0", NULL),
3660};
3661static struct regulator_consumer_supply vreg_consumers_PM8058_L1[] = {
3662 REGULATOR_SUPPLY("8058_l1", NULL),
3663};
3664static struct regulator_consumer_supply vreg_consumers_PM8058_L2[] = {
3665 REGULATOR_SUPPLY("8058_l2", NULL),
3666};
3667static struct regulator_consumer_supply vreg_consumers_PM8058_L3[] = {
3668 REGULATOR_SUPPLY("8058_l3", NULL),
3669};
3670static struct regulator_consumer_supply vreg_consumers_PM8058_L4[] = {
3671 REGULATOR_SUPPLY("8058_l4", NULL),
3672};
3673static struct regulator_consumer_supply vreg_consumers_PM8058_L5[] = {
3674 REGULATOR_SUPPLY("8058_l5", NULL),
3675};
3676static struct regulator_consumer_supply vreg_consumers_PM8058_L6[] = {
3677 REGULATOR_SUPPLY("8058_l6", NULL),
3678};
3679static struct regulator_consumer_supply vreg_consumers_PM8058_L7[] = {
3680 REGULATOR_SUPPLY("8058_l7", NULL),
3681};
3682static struct regulator_consumer_supply vreg_consumers_PM8058_L8[] = {
3683 REGULATOR_SUPPLY("8058_l8", NULL),
3684};
3685static struct regulator_consumer_supply vreg_consumers_PM8058_L9[] = {
3686 REGULATOR_SUPPLY("8058_l9", NULL),
3687};
3688static struct regulator_consumer_supply vreg_consumers_PM8058_L10[] = {
3689 REGULATOR_SUPPLY("8058_l10", NULL),
3690};
3691static struct regulator_consumer_supply vreg_consumers_PM8058_L11[] = {
3692 REGULATOR_SUPPLY("8058_l11", NULL),
3693};
3694static struct regulator_consumer_supply vreg_consumers_PM8058_L12[] = {
3695 REGULATOR_SUPPLY("8058_l12", NULL),
3696};
3697static struct regulator_consumer_supply vreg_consumers_PM8058_L13[] = {
3698 REGULATOR_SUPPLY("8058_l13", NULL),
3699};
3700static struct regulator_consumer_supply vreg_consumers_PM8058_L14[] = {
3701 REGULATOR_SUPPLY("8058_l14", NULL),
3702};
3703static struct regulator_consumer_supply vreg_consumers_PM8058_L15[] = {
3704 REGULATOR_SUPPLY("8058_l15", NULL),
3705};
3706static struct regulator_consumer_supply vreg_consumers_PM8058_L16[] = {
3707 REGULATOR_SUPPLY("8058_l16", NULL),
3708};
3709static struct regulator_consumer_supply vreg_consumers_PM8058_L17[] = {
3710 REGULATOR_SUPPLY("8058_l17", NULL),
3711};
3712static struct regulator_consumer_supply vreg_consumers_PM8058_L18[] = {
3713 REGULATOR_SUPPLY("8058_l18", NULL),
3714};
3715static struct regulator_consumer_supply vreg_consumers_PM8058_L19[] = {
3716 REGULATOR_SUPPLY("8058_l19", NULL),
3717};
3718static struct regulator_consumer_supply vreg_consumers_PM8058_L20[] = {
3719 REGULATOR_SUPPLY("8058_l20", NULL),
3720};
3721static struct regulator_consumer_supply vreg_consumers_PM8058_L21[] = {
3722 REGULATOR_SUPPLY("8058_l21", NULL),
3723};
3724static struct regulator_consumer_supply vreg_consumers_PM8058_L22[] = {
3725 REGULATOR_SUPPLY("8058_l22", NULL),
3726};
3727static struct regulator_consumer_supply vreg_consumers_PM8058_L23[] = {
3728 REGULATOR_SUPPLY("8058_l23", NULL),
3729};
3730static struct regulator_consumer_supply vreg_consumers_PM8058_L24[] = {
3731 REGULATOR_SUPPLY("8058_l24", NULL),
3732};
3733static struct regulator_consumer_supply vreg_consumers_PM8058_L25[] = {
3734 REGULATOR_SUPPLY("8058_l25", NULL),
3735};
3736static struct regulator_consumer_supply vreg_consumers_PM8058_S0[] = {
3737 REGULATOR_SUPPLY("8058_s0", NULL),
3738};
3739static struct regulator_consumer_supply vreg_consumers_PM8058_S1[] = {
3740 REGULATOR_SUPPLY("8058_s1", NULL),
3741};
3742static struct regulator_consumer_supply vreg_consumers_PM8058_S2[] = {
3743 REGULATOR_SUPPLY("8058_s2", NULL),
3744};
3745static struct regulator_consumer_supply vreg_consumers_PM8058_S3[] = {
3746 REGULATOR_SUPPLY("8058_s3", NULL),
3747};
3748static struct regulator_consumer_supply vreg_consumers_PM8058_S4[] = {
3749 REGULATOR_SUPPLY("8058_s4", NULL),
3750};
3751static struct regulator_consumer_supply vreg_consumers_PM8058_LVS0[] = {
3752 REGULATOR_SUPPLY("8058_lvs0", NULL),
3753};
3754static struct regulator_consumer_supply vreg_consumers_PM8058_LVS1[] = {
3755 REGULATOR_SUPPLY("8058_lvs1", NULL),
3756};
3757static struct regulator_consumer_supply vreg_consumers_PM8058_NCP[] = {
3758 REGULATOR_SUPPLY("8058_ncp", NULL),
3759};
3760
3761static struct regulator_consumer_supply vreg_consumers_PM8901_L0[] = {
3762 REGULATOR_SUPPLY("8901_l0", NULL),
3763};
3764static struct regulator_consumer_supply vreg_consumers_PM8901_L1[] = {
3765 REGULATOR_SUPPLY("8901_l1", NULL),
3766};
3767static struct regulator_consumer_supply vreg_consumers_PM8901_L2[] = {
3768 REGULATOR_SUPPLY("8901_l2", NULL),
3769};
3770static struct regulator_consumer_supply vreg_consumers_PM8901_L3[] = {
3771 REGULATOR_SUPPLY("8901_l3", NULL),
3772};
3773static struct regulator_consumer_supply vreg_consumers_PM8901_L4[] = {
3774 REGULATOR_SUPPLY("8901_l4", NULL),
3775};
3776static struct regulator_consumer_supply vreg_consumers_PM8901_L5[] = {
3777 REGULATOR_SUPPLY("8901_l5", NULL),
3778};
3779static struct regulator_consumer_supply vreg_consumers_PM8901_L6[] = {
3780 REGULATOR_SUPPLY("8901_l6", NULL),
3781};
3782static struct regulator_consumer_supply vreg_consumers_PM8901_S2[] = {
3783 REGULATOR_SUPPLY("8901_s2", NULL),
3784};
3785static struct regulator_consumer_supply vreg_consumers_PM8901_S3[] = {
3786 REGULATOR_SUPPLY("8901_s3", NULL),
3787};
3788static struct regulator_consumer_supply vreg_consumers_PM8901_S4[] = {
3789 REGULATOR_SUPPLY("8901_s4", NULL),
3790};
3791static struct regulator_consumer_supply vreg_consumers_PM8901_LVS0[] = {
3792 REGULATOR_SUPPLY("8901_lvs0", NULL),
3793};
3794static struct regulator_consumer_supply vreg_consumers_PM8901_LVS1[] = {
3795 REGULATOR_SUPPLY("8901_lvs1", NULL),
3796};
3797static struct regulator_consumer_supply vreg_consumers_PM8901_LVS2[] = {
3798 REGULATOR_SUPPLY("8901_lvs2", NULL),
3799};
3800static struct regulator_consumer_supply vreg_consumers_PM8901_LVS3[] = {
3801 REGULATOR_SUPPLY("8901_lvs3", NULL),
3802};
3803static struct regulator_consumer_supply vreg_consumers_PM8901_MVS0[] = {
3804 REGULATOR_SUPPLY("8901_mvs0", NULL),
3805};
3806
3807#define RPM_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
3808 _default_uV, _peak_uA, _avg_uA, _pull_down, _pin_ctrl, \
3809 _freq, _pin_fn, _rpm_mode, _state, _sleep_selectable, \
3810 _always_on) \
3811 [RPM_VREG_ID_##_id] = { \
3812 .init_data = { \
3813 .constraints = { \
3814 .valid_modes_mask = _modes, \
3815 .valid_ops_mask = _ops, \
3816 .min_uV = _min_uV, \
3817 .max_uV = _max_uV, \
3818 .input_uV = _min_uV, \
3819 .apply_uV = _apply_uV, \
3820 .always_on = _always_on, \
3821 }, \
3822 .consumer_supplies = vreg_consumers_##_id, \
3823 .num_consumer_supplies = \
3824 ARRAY_SIZE(vreg_consumers_##_id), \
3825 }, \
3826 .default_uV = _default_uV, \
3827 .peak_uA = _peak_uA, \
3828 .avg_uA = _avg_uA, \
3829 .pull_down_enable = _pull_down, \
3830 .pin_ctrl = _pin_ctrl, \
3831 .freq = _freq, \
3832 .pin_fn = _pin_fn, \
3833 .mode = _rpm_mode, \
3834 .state = _state, \
3835 .sleep_selectable = _sleep_selectable, \
3836 }
3837
3838/*
3839 * The default LPM/HPM state of an RPM controlled regulator can be controlled
3840 * via the peak_uA value specified in the table below. If the value is less
3841 * than the high power min threshold for the regulator, then the regulator will
3842 * be set to LPM. Otherwise, it will be set to HPM.
3843 *
3844 * This value can be further overridden by specifying an initial mode via
3845 * .init_data.constraints.initial_mode.
3846 */
3847
3848#define RPM_VREG_INIT_LDO(_id, _always_on, _pd, _sleep_selectable, _min_uV, \
3849 _max_uV, _init_peak_uA, _pin_ctrl) \
3850 RPM_VREG_INIT(_id, _min_uV, _max_uV, REGULATOR_MODE_FAST | \
3851 REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE | \
3852 REGULATOR_MODE_STANDBY, REGULATOR_CHANGE_VOLTAGE | \
3853 REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
3854 REGULATOR_CHANGE_DRMS, 0, _min_uV, _init_peak_uA, \
3855 _init_peak_uA, _pd, _pin_ctrl, RPM_VREG_FREQ_NONE, \
3856 RPM_VREG_PIN_FN_ENABLE, RPM_VREG_MODE_NONE, \
3857 RPM_VREG_STATE_OFF, _sleep_selectable, _always_on)
3858
3859#define RPM_VREG_INIT_LDO_PF(_id, _always_on, _pd, _sleep_selectable, _min_uV, \
3860 _max_uV, _init_peak_uA, _pin_ctrl, _pin_fn) \
3861 RPM_VREG_INIT(_id, _min_uV, _max_uV, REGULATOR_MODE_FAST | \
3862 REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE | \
3863 REGULATOR_MODE_STANDBY, REGULATOR_CHANGE_VOLTAGE | \
3864 REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
3865 REGULATOR_CHANGE_DRMS, 0, _min_uV, _init_peak_uA, \
3866 _init_peak_uA, _pd, _pin_ctrl, RPM_VREG_FREQ_NONE, \
3867 _pin_fn, RPM_VREG_MODE_NONE, RPM_VREG_STATE_OFF, \
3868 _sleep_selectable, _always_on)
3869
3870#define RPM_VREG_INIT_SMPS(_id, _always_on, _pd, _sleep_selectable, _min_uV, \
3871 _max_uV, _init_peak_uA, _pin_ctrl, _freq) \
3872 RPM_VREG_INIT(_id, _min_uV, _max_uV, REGULATOR_MODE_FAST | \
3873 REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE | \
3874 REGULATOR_MODE_STANDBY, REGULATOR_CHANGE_VOLTAGE | \
3875 REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE | \
3876 REGULATOR_CHANGE_DRMS, 0, _min_uV, _init_peak_uA, \
3877 _init_peak_uA, _pd, _pin_ctrl, _freq, \
3878 RPM_VREG_PIN_FN_ENABLE, RPM_VREG_MODE_NONE, \
3879 RPM_VREG_STATE_OFF, _sleep_selectable, _always_on)
3880
3881#define RPM_VREG_INIT_VS(_id, _always_on, _pd, _sleep_selectable, _pin_ctrl) \
3882 RPM_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE, \
3883 REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE, 0, 0, \
3884 1000, 1000, _pd, _pin_ctrl, RPM_VREG_FREQ_NONE, \
3885 RPM_VREG_PIN_FN_ENABLE, RPM_VREG_MODE_NONE, \
3886 RPM_VREG_STATE_OFF, _sleep_selectable, _always_on)
3887
3888#define RPM_VREG_INIT_NCP(_id, _always_on, _pd, _sleep_selectable, _min_uV, \
3889 _max_uV, _pin_ctrl) \
3890 RPM_VREG_INIT(_id, _min_uV, _max_uV, REGULATOR_MODE_NORMAL, \
3891 REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS, 0, \
3892 _min_uV, 1000, 1000, _pd, _pin_ctrl, RPM_VREG_FREQ_NONE, \
3893 RPM_VREG_PIN_FN_ENABLE, RPM_VREG_MODE_NONE, \
3894 RPM_VREG_STATE_OFF, _sleep_selectable, _always_on)
3895
3896#define LDO50HMIN RPM_VREG_LDO_50_HPM_MIN_LOAD
3897#define LDO150HMIN RPM_VREG_LDO_150_HPM_MIN_LOAD
3898#define LDO300HMIN RPM_VREG_LDO_300_HPM_MIN_LOAD
3899#define SMPS_HMIN RPM_VREG_SMPS_HPM_MIN_LOAD
3900#define FTS_HMIN RPM_VREG_FTSMPS_HPM_MIN_LOAD
3901
3902static struct rpm_vreg_pdata rpm_vreg_init_pdata[RPM_VREG_ID_MAX] = {
3903 RPM_VREG_INIT_LDO(PM8058_L0, 0, 1, 0, 1200000, 1200000, LDO150HMIN, 0),
3904 RPM_VREG_INIT_LDO(PM8058_L1, 0, 1, 0, 1200000, 1200000, LDO300HMIN, 0),
3905 RPM_VREG_INIT_LDO(PM8058_L2, 0, 1, 0, 1800000, 2600000, LDO300HMIN, 0),
3906 RPM_VREG_INIT_LDO(PM8058_L3, 0, 1, 0, 1800000, 1800000, LDO150HMIN, 0),
3907 RPM_VREG_INIT_LDO(PM8058_L4, 0, 1, 0, 2850000, 2850000, LDO50HMIN, 0),
3908 RPM_VREG_INIT_LDO(PM8058_L5, 0, 1, 0, 2850000, 2850000, LDO300HMIN, 0),
3909 RPM_VREG_INIT_LDO(PM8058_L6, 0, 1, 0, 3000000, 3600000, LDO50HMIN, 0),
3910 RPM_VREG_INIT_LDO(PM8058_L7, 0, 1, 0, 1800000, 1800000, LDO50HMIN, 0),
3911 RPM_VREG_INIT_LDO_PF(PM8058_L8, 0, 1, 0, 2900000, 3050000, LDO300HMIN,
3912 RPM_VREG_PIN_CTRL_NONE, RPM_VREG_PIN_FN_SLEEP_B),
3913 RPM_VREG_INIT_LDO(PM8058_L9, 0, 1, 0, 1800000, 1800000, LDO300HMIN, 0),
3914 RPM_VREG_INIT_LDO(PM8058_L10, 0, 1, 0, 2600000, 2600000, LDO300HMIN, 0),
3915 RPM_VREG_INIT_LDO(PM8058_L11, 0, 1, 0, 1500000, 1500000, LDO150HMIN, 0),
3916 RPM_VREG_INIT_LDO(PM8058_L12, 0, 1, 0, 2900000, 2900000, LDO150HMIN, 0),
3917 RPM_VREG_INIT_LDO(PM8058_L13, 0, 1, 0, 2050000, 2050000, LDO300HMIN, 0),
3918 RPM_VREG_INIT_LDO(PM8058_L14, 0, 0, 0, 2850000, 2850000, LDO300HMIN, 0),
3919 RPM_VREG_INIT_LDO(PM8058_L15, 0, 1, 0, 2850000, 2850000, LDO300HMIN, 0),
3920 RPM_VREG_INIT_LDO(PM8058_L16, 1, 1, 0, 1800000, 1800000, LDO300HMIN, 0),
3921 RPM_VREG_INIT_LDO(PM8058_L17, 0, 1, 0, 2600000, 2600000, LDO150HMIN, 0),
3922 RPM_VREG_INIT_LDO(PM8058_L18, 0, 1, 0, 2200000, 2200000, LDO150HMIN, 0),
3923 RPM_VREG_INIT_LDO(PM8058_L19, 0, 1, 0, 2500000, 2500000, LDO150HMIN, 0),
3924 RPM_VREG_INIT_LDO_PF(PM8058_L20, 0, 1, 0, 1800000, 1800000, LDO150HMIN,
3925 RPM_VREG_PIN_CTRL_NONE, RPM_VREG_PIN_FN_SLEEP_B),
3926 RPM_VREG_INIT_LDO_PF(PM8058_L21, 1, 1, 0, 1200000, 1200000, LDO150HMIN,
3927 RPM_VREG_PIN_CTRL_NONE, RPM_VREG_PIN_FN_SLEEP_B),
David Collins3cfb9652011-07-27 14:24:36 -07003928 RPM_VREG_INIT_LDO(PM8058_L22, 0, 1, 0, 1150000, 1150000, LDO300HMIN, 0),
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003929 RPM_VREG_INIT_LDO(PM8058_L23, 0, 1, 0, 1200000, 1200000, LDO300HMIN, 0),
3930 RPM_VREG_INIT_LDO(PM8058_L24, 0, 1, 0, 1200000, 1200000, LDO150HMIN, 0),
3931 RPM_VREG_INIT_LDO(PM8058_L25, 0, 1, 0, 1200000, 1200000, LDO150HMIN, 0),
3932
3933 RPM_VREG_INIT_SMPS(PM8058_S0, 0, 1, 1, 500000, 1250000, SMPS_HMIN, 0,
3934 RPM_VREG_FREQ_1p60),
3935 RPM_VREG_INIT_SMPS(PM8058_S1, 0, 1, 1, 500000, 1250000, SMPS_HMIN, 0,
3936 RPM_VREG_FREQ_1p60),
3937 RPM_VREG_INIT_SMPS(PM8058_S2, 0, 1, 1, 1200000, 1400000, SMPS_HMIN,
3938 RPM_VREG_PIN_CTRL_A0, RPM_VREG_FREQ_1p60),
3939 RPM_VREG_INIT_SMPS(PM8058_S3, 1, 1, 0, 1800000, 1800000, SMPS_HMIN, 0,
3940 RPM_VREG_FREQ_1p60),
3941 RPM_VREG_INIT_SMPS(PM8058_S4, 1, 1, 0, 2200000, 2200000, SMPS_HMIN, 0,
3942 RPM_VREG_FREQ_1p60),
3943
3944 RPM_VREG_INIT_VS(PM8058_LVS0, 0, 1, 0, 0),
3945 RPM_VREG_INIT_VS(PM8058_LVS1, 0, 1, 0, 0),
3946
3947 RPM_VREG_INIT_NCP(PM8058_NCP, 0, 1, 0, 1800000, 1800000, 0),
3948
3949 RPM_VREG_INIT_LDO(PM8901_L0, 0, 1, 0, 1200000, 1200000, LDO300HMIN,
3950 RPM_VREG_PIN_CTRL_A0),
3951 RPM_VREG_INIT_LDO(PM8901_L1, 0, 1, 0, 3300000, 3300000, LDO300HMIN, 0),
3952 RPM_VREG_INIT_LDO(PM8901_L2, 0, 1, 0, 2850000, 3300000, LDO300HMIN, 0),
3953 RPM_VREG_INIT_LDO(PM8901_L3, 0, 1, 0, 3300000, 3300000, LDO300HMIN, 0),
3954 RPM_VREG_INIT_LDO(PM8901_L4, 0, 1, 0, 2600000, 2600000, LDO300HMIN, 0),
3955 RPM_VREG_INIT_LDO(PM8901_L5, 0, 1, 0, 2850000, 2850000, LDO300HMIN, 0),
3956 RPM_VREG_INIT_LDO(PM8901_L6, 0, 1, 0, 2200000, 2200000, LDO300HMIN, 0),
3957
3958 RPM_VREG_INIT_SMPS(PM8901_S2, 0, 1, 0, 1300000, 1300000, FTS_HMIN, 0,
3959 RPM_VREG_FREQ_1p60),
3960 RPM_VREG_INIT_SMPS(PM8901_S3, 0, 1, 0, 1100000, 1100000, FTS_HMIN, 0,
3961 RPM_VREG_FREQ_1p60),
3962 RPM_VREG_INIT_SMPS(PM8901_S4, 0, 1, 0, 1225000, 1225000, FTS_HMIN,
3963 RPM_VREG_PIN_CTRL_A0, RPM_VREG_FREQ_1p60),
3964
3965 RPM_VREG_INIT_VS(PM8901_LVS0, 1, 1, 0, 0),
3966 RPM_VREG_INIT_VS(PM8901_LVS1, 0, 1, 0, 0),
3967 RPM_VREG_INIT_VS(PM8901_LVS2, 0, 1, 0, 0),
3968 RPM_VREG_INIT_VS(PM8901_LVS3, 0, 1, 0, 0),
3969 RPM_VREG_INIT_VS(PM8901_MVS0, 0, 1, 0, 0),
3970};
3971
3972#define RPM_VREG(_id) \
3973 [_id] = { \
3974 .name = "rpm-regulator", \
3975 .id = _id, \
3976 .dev = { \
3977 .platform_data = &rpm_vreg_init_pdata[_id], \
3978 }, \
3979 }
3980
3981static struct platform_device rpm_vreg_device[RPM_VREG_ID_MAX] = {
3982 RPM_VREG(RPM_VREG_ID_PM8058_L0),
3983 RPM_VREG(RPM_VREG_ID_PM8058_L1),
3984 RPM_VREG(RPM_VREG_ID_PM8058_L2),
3985 RPM_VREG(RPM_VREG_ID_PM8058_L3),
3986 RPM_VREG(RPM_VREG_ID_PM8058_L4),
3987 RPM_VREG(RPM_VREG_ID_PM8058_L5),
3988 RPM_VREG(RPM_VREG_ID_PM8058_L6),
3989 RPM_VREG(RPM_VREG_ID_PM8058_L7),
3990 RPM_VREG(RPM_VREG_ID_PM8058_L8),
3991 RPM_VREG(RPM_VREG_ID_PM8058_L9),
3992 RPM_VREG(RPM_VREG_ID_PM8058_L10),
3993 RPM_VREG(RPM_VREG_ID_PM8058_L11),
3994 RPM_VREG(RPM_VREG_ID_PM8058_L12),
3995 RPM_VREG(RPM_VREG_ID_PM8058_L13),
3996 RPM_VREG(RPM_VREG_ID_PM8058_L14),
3997 RPM_VREG(RPM_VREG_ID_PM8058_L15),
3998 RPM_VREG(RPM_VREG_ID_PM8058_L16),
3999 RPM_VREG(RPM_VREG_ID_PM8058_L17),
4000 RPM_VREG(RPM_VREG_ID_PM8058_L18),
4001 RPM_VREG(RPM_VREG_ID_PM8058_L19),
4002 RPM_VREG(RPM_VREG_ID_PM8058_L20),
4003 RPM_VREG(RPM_VREG_ID_PM8058_L21),
4004 RPM_VREG(RPM_VREG_ID_PM8058_L22),
4005 RPM_VREG(RPM_VREG_ID_PM8058_L23),
4006 RPM_VREG(RPM_VREG_ID_PM8058_L24),
4007 RPM_VREG(RPM_VREG_ID_PM8058_L25),
4008 RPM_VREG(RPM_VREG_ID_PM8058_S0),
4009 RPM_VREG(RPM_VREG_ID_PM8058_S1),
4010 RPM_VREG(RPM_VREG_ID_PM8058_S2),
4011 RPM_VREG(RPM_VREG_ID_PM8058_S3),
4012 RPM_VREG(RPM_VREG_ID_PM8058_S4),
4013 RPM_VREG(RPM_VREG_ID_PM8058_LVS0),
4014 RPM_VREG(RPM_VREG_ID_PM8058_LVS1),
4015 RPM_VREG(RPM_VREG_ID_PM8058_NCP),
4016 RPM_VREG(RPM_VREG_ID_PM8901_L0),
4017 RPM_VREG(RPM_VREG_ID_PM8901_L1),
4018 RPM_VREG(RPM_VREG_ID_PM8901_L2),
4019 RPM_VREG(RPM_VREG_ID_PM8901_L3),
4020 RPM_VREG(RPM_VREG_ID_PM8901_L4),
4021 RPM_VREG(RPM_VREG_ID_PM8901_L5),
4022 RPM_VREG(RPM_VREG_ID_PM8901_L6),
4023 RPM_VREG(RPM_VREG_ID_PM8901_S2),
4024 RPM_VREG(RPM_VREG_ID_PM8901_S3),
4025 RPM_VREG(RPM_VREG_ID_PM8901_S4),
4026 RPM_VREG(RPM_VREG_ID_PM8901_LVS0),
4027 RPM_VREG(RPM_VREG_ID_PM8901_LVS1),
4028 RPM_VREG(RPM_VREG_ID_PM8901_LVS2),
4029 RPM_VREG(RPM_VREG_ID_PM8901_LVS3),
4030 RPM_VREG(RPM_VREG_ID_PM8901_MVS0),
4031};
4032
4033static struct platform_device *early_regulators[] __initdata = {
4034 &msm_device_saw_s0,
4035 &msm_device_saw_s1,
4036#ifdef CONFIG_PMIC8058
4037 &rpm_vreg_device[RPM_VREG_ID_PM8058_S0],
4038 &rpm_vreg_device[RPM_VREG_ID_PM8058_S1],
4039#endif
4040};
4041
4042static struct platform_device *early_devices[] __initdata = {
4043#ifdef CONFIG_MSM_BUS_SCALING
4044 &msm_bus_apps_fabric,
4045 &msm_bus_sys_fabric,
4046 &msm_bus_mm_fabric,
4047 &msm_bus_sys_fpb,
4048 &msm_bus_cpss_fpb,
4049#endif
4050 &msm_device_dmov_adm0,
4051 &msm_device_dmov_adm1,
4052};
4053
4054#if (defined(CONFIG_MARIMBA_CORE)) && \
4055 (defined(CONFIG_MSM_BT_POWER) || defined(CONFIG_MSM_BT_POWER_MODULE))
4056
4057static int bluetooth_power(int);
4058static struct platform_device msm_bt_power_device = {
4059 .name = "bt_power",
4060 .id = -1,
4061 .dev = {
4062 .platform_data = &bluetooth_power,
4063 },
4064};
4065#endif
4066
4067static struct platform_device msm_tsens_device = {
4068 .name = "tsens-tm",
4069 .id = -1,
4070};
4071
4072static struct platform_device *rumi_sim_devices[] __initdata = {
4073 &smc91x_device,
4074 &msm_device_uart_dm12,
4075#ifdef CONFIG_I2C_QUP
4076 &msm_gsbi3_qup_i2c_device,
4077 &msm_gsbi4_qup_i2c_device,
4078 &msm_gsbi7_qup_i2c_device,
4079 &msm_gsbi8_qup_i2c_device,
4080 &msm_gsbi9_qup_i2c_device,
4081 &msm_gsbi12_qup_i2c_device,
4082#endif
4083#ifdef CONFIG_I2C_SSBI
4084 &msm_device_ssbi1,
4085 &msm_device_ssbi2,
4086 &msm_device_ssbi3,
4087#endif
4088#ifdef CONFIG_ANDROID_PMEM
4089 &android_pmem_device,
4090 &android_pmem_adsp_device,
4091 &android_pmem_audio_device,
4092 &android_pmem_smipool_device,
4093#endif
4094#ifdef CONFIG_MSM_ROTATOR
4095 &msm_rotator_device,
4096#endif
4097 &msm_fb_device,
4098 &msm_kgsl_3d0,
4099 &msm_kgsl_2d0,
4100 &msm_kgsl_2d1,
4101 &lcdc_samsung_panel_device,
4102#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
4103 &hdmi_msm_device,
4104#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
4105#ifdef CONFIG_MSM_CAMERA
4106#ifdef CONFIG_MT9E013
4107 &msm_camera_sensor_mt9e013,
4108#endif
4109#ifdef CONFIG_IMX074
4110 &msm_camera_sensor_imx074,
4111#endif
Jilai Wang971f97f2011-07-13 14:25:25 -04004112#ifdef CONFIG_VX6953
4113 &msm_camera_sensor_vx6953,
4114#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004115#ifdef CONFIG_WEBCAM_OV7692
4116 &msm_camera_sensor_webcam_ov7692,
4117#endif
4118#ifdef CONFIG_WEBCAM_OV9726
4119 &msm_camera_sensor_webcam_ov9726,
4120#endif
4121#ifdef CONFIG_QS_S5K4E1
4122 &msm_camera_sensor_qs_s5k4e1,
4123#endif
4124#endif
4125#ifdef CONFIG_MSM_GEMINI
4126 &msm_gemini_device,
4127#endif
4128#ifdef CONFIG_MSM_VPE
4129 &msm_vpe_device,
4130#endif
4131 &msm_device_vidc,
4132};
4133
4134#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
4135enum {
4136 SX150X_CORE,
4137 SX150X_DOCKING,
4138 SX150X_SURF,
4139 SX150X_LEFT_FHA,
4140 SX150X_RIGHT_FHA,
4141 SX150X_SOUTH,
4142 SX150X_NORTH,
4143 SX150X_CORE_FLUID,
4144};
4145
4146static struct sx150x_platform_data sx150x_data[] __initdata = {
4147 [SX150X_CORE] = {
4148 .gpio_base = GPIO_CORE_EXPANDER_BASE,
4149 .oscio_is_gpo = false,
4150 .io_pullup_ena = 0x0c08,
4151 .io_pulldn_ena = 0x4060,
4152 .io_open_drain_ena = 0x000c,
4153 .io_polarity = 0,
4154 .irq_summary = -1, /* see fixup_i2c_configs() */
4155 .irq_base = GPIO_EXPANDER_IRQ_BASE,
4156 },
4157 [SX150X_DOCKING] = {
4158 .gpio_base = GPIO_DOCKING_EXPANDER_BASE,
4159 .oscio_is_gpo = false,
4160 .io_pullup_ena = 0x5e06,
4161 .io_pulldn_ena = 0x81b8,
4162 .io_open_drain_ena = 0,
4163 .io_polarity = 0,
4164 .irq_summary = PM8058_GPIO_IRQ(PM8058_IRQ_BASE,
4165 UI_INT2_N),
4166 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4167 GPIO_DOCKING_EXPANDER_BASE -
4168 GPIO_EXPANDER_GPIO_BASE,
4169 },
4170 [SX150X_SURF] = {
4171 .gpio_base = GPIO_SURF_EXPANDER_BASE,
4172 .oscio_is_gpo = false,
4173 .io_pullup_ena = 0,
4174 .io_pulldn_ena = 0,
4175 .io_open_drain_ena = 0,
4176 .io_polarity = 0,
4177 .irq_summary = PM8058_GPIO_IRQ(PM8058_IRQ_BASE,
4178 UI_INT1_N),
4179 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4180 GPIO_SURF_EXPANDER_BASE -
4181 GPIO_EXPANDER_GPIO_BASE,
4182 },
4183 [SX150X_LEFT_FHA] = {
4184 .gpio_base = GPIO_LEFT_KB_EXPANDER_BASE,
4185 .oscio_is_gpo = false,
4186 .io_pullup_ena = 0,
4187 .io_pulldn_ena = 0x40,
4188 .io_open_drain_ena = 0,
4189 .io_polarity = 0,
4190 .irq_summary = PM8058_GPIO_IRQ(PM8058_IRQ_BASE,
4191 UI_INT3_N),
4192 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4193 GPIO_LEFT_KB_EXPANDER_BASE -
4194 GPIO_EXPANDER_GPIO_BASE,
4195 },
4196 [SX150X_RIGHT_FHA] = {
4197 .gpio_base = GPIO_RIGHT_KB_EXPANDER_BASE,
4198 .oscio_is_gpo = true,
4199 .io_pullup_ena = 0,
4200 .io_pulldn_ena = 0,
4201 .io_open_drain_ena = 0,
4202 .io_polarity = 0,
4203 .irq_summary = PM8058_GPIO_IRQ(PM8058_IRQ_BASE,
4204 UI_INT3_N),
4205 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4206 GPIO_RIGHT_KB_EXPANDER_BASE -
4207 GPIO_EXPANDER_GPIO_BASE,
4208 },
4209 [SX150X_SOUTH] = {
4210 .gpio_base = GPIO_SOUTH_EXPANDER_BASE,
4211 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4212 GPIO_SOUTH_EXPANDER_BASE -
4213 GPIO_EXPANDER_GPIO_BASE,
4214 .irq_summary = PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT3_N),
4215 },
4216 [SX150X_NORTH] = {
4217 .gpio_base = GPIO_NORTH_EXPANDER_BASE,
4218 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4219 GPIO_NORTH_EXPANDER_BASE -
4220 GPIO_EXPANDER_GPIO_BASE,
4221 .irq_summary = PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT3_N),
4222 .oscio_is_gpo = true,
4223 .io_open_drain_ena = 0x30,
4224 },
4225 [SX150X_CORE_FLUID] = {
4226 .gpio_base = GPIO_CORE_EXPANDER_BASE,
4227 .oscio_is_gpo = false,
4228 .io_pullup_ena = 0x0408,
4229 .io_pulldn_ena = 0x4060,
4230 .io_open_drain_ena = 0x0008,
4231 .io_polarity = 0,
4232 .irq_summary = -1, /* see fixup_i2c_configs() */
4233 .irq_base = GPIO_EXPANDER_IRQ_BASE,
4234 },
4235};
4236
4237#ifdef CONFIG_SENSORS_MSM_ADC
4238/* Configuration of EPM expander is done when client
4239 * request an adc read
4240 */
4241static struct sx150x_platform_data sx150x_epmdata = {
4242 .gpio_base = GPIO_EPM_EXPANDER_BASE,
4243 .irq_base = GPIO_EXPANDER_IRQ_BASE +
4244 GPIO_EPM_EXPANDER_BASE -
4245 GPIO_EXPANDER_GPIO_BASE,
4246 .irq_summary = -1,
4247};
4248#endif
4249
4250/* sx150x_low_power_cfg
4251 *
4252 * This data and init function are used to put unused gpio-expander output
4253 * lines into their low-power states at boot. The init
4254 * function must be deferred until a later init stage because the i2c
4255 * gpio expander drivers do not probe until after they are registered
4256 * (see register_i2c_devices) and the work-queues for those registrations
4257 * are processed. Because these lines are unused, there is no risk of
4258 * competing with a device driver for the gpio.
4259 *
4260 * gpio lines whose low-power states are input are naturally in their low-
4261 * power configurations once probed, see the platform data structures above.
4262 */
4263struct sx150x_low_power_cfg {
4264 unsigned gpio;
4265 unsigned val;
4266};
4267
4268static struct sx150x_low_power_cfg
4269common_sx150x_lp_cfgs[] __initdata = {
4270 {GPIO_WLAN_DEEP_SLEEP_N, 0},
4271 {GPIO_EXT_GPS_LNA_EN, 0},
4272 {GPIO_MSM_WAKES_BT, 0},
4273 {GPIO_USB_UICC_EN, 0},
4274 {GPIO_BATT_GAUGE_EN, 0},
4275};
4276
4277static struct sx150x_low_power_cfg
4278surf_ffa_sx150x_lp_cfgs[] __initdata = {
4279 {GPIO_MIPI_DSI_RST_N, 0},
4280 {GPIO_DONGLE_PWR_EN, 0},
4281 {GPIO_CAP_TS_SLEEP, 1},
4282 {GPIO_WEB_CAMIF_RESET_N, 0},
4283};
4284
4285static void __init
4286cfg_gpio_low_power(struct sx150x_low_power_cfg *cfgs, unsigned nelems)
4287{
4288 unsigned n;
4289 int rc;
4290
4291 for (n = 0; n < nelems; ++n) {
4292 rc = gpio_request(cfgs[n].gpio, NULL);
4293 if (!rc) {
4294 rc = gpio_direction_output(cfgs[n].gpio, cfgs[n].val);
4295 gpio_free(cfgs[n].gpio);
4296 }
4297
4298 if (rc) {
4299 printk(KERN_NOTICE "%s: failed to sleep gpio %d: %d\n",
4300 __func__, cfgs[n].gpio, rc);
4301 }
Steve Muckle9161d302010-02-11 11:50:40 -08004302 }
Steve Mucklea55df6e2010-01-07 12:43:24 -08004303}
4304
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004305static int __init cfg_sx150xs_low_power(void)
Steve Mucklea55df6e2010-01-07 12:43:24 -08004306{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004307 cfg_gpio_low_power(common_sx150x_lp_cfgs,
4308 ARRAY_SIZE(common_sx150x_lp_cfgs));
4309 if (!machine_is_msm8x60_fluid())
4310 cfg_gpio_low_power(surf_ffa_sx150x_lp_cfgs,
4311 ARRAY_SIZE(surf_ffa_sx150x_lp_cfgs));
4312 return 0;
4313}
4314module_init(cfg_sx150xs_low_power);
4315
4316#ifdef CONFIG_I2C
4317static struct i2c_board_info core_expander_i2c_info[] __initdata = {
4318 {
4319 I2C_BOARD_INFO("sx1509q", 0x3e),
4320 .platform_data = &sx150x_data[SX150X_CORE]
4321 },
4322};
4323
4324static struct i2c_board_info docking_expander_i2c_info[] __initdata = {
4325 {
4326 I2C_BOARD_INFO("sx1509q", 0x3f),
4327 .platform_data = &sx150x_data[SX150X_DOCKING]
4328 },
4329};
4330
4331static struct i2c_board_info surf_expanders_i2c_info[] __initdata = {
4332 {
4333 I2C_BOARD_INFO("sx1509q", 0x70),
4334 .platform_data = &sx150x_data[SX150X_SURF]
4335 }
4336};
4337
4338static struct i2c_board_info fha_expanders_i2c_info[] __initdata = {
4339 {
4340 I2C_BOARD_INFO("sx1508q", 0x21),
4341 .platform_data = &sx150x_data[SX150X_LEFT_FHA]
4342 },
4343 {
4344 I2C_BOARD_INFO("sx1508q", 0x22),
4345 .platform_data = &sx150x_data[SX150X_RIGHT_FHA]
4346 }
4347};
4348
4349static struct i2c_board_info fluid_expanders_i2c_info[] __initdata = {
4350 {
4351 I2C_BOARD_INFO("sx1508q", 0x23),
4352 .platform_data = &sx150x_data[SX150X_SOUTH]
4353 },
4354 {
4355 I2C_BOARD_INFO("sx1508q", 0x20),
4356 .platform_data = &sx150x_data[SX150X_NORTH]
4357 }
4358};
4359
4360static struct i2c_board_info fluid_core_expander_i2c_info[] __initdata = {
4361 {
4362 I2C_BOARD_INFO("sx1509q", 0x3e),
4363 .platform_data = &sx150x_data[SX150X_CORE_FLUID]
4364 },
4365};
4366
4367#ifdef CONFIG_SENSORS_MSM_ADC
4368static struct i2c_board_info fluid_expanders_i2c_epm_info[] = {
4369 {
4370 I2C_BOARD_INFO("sx1509q", 0x3e),
4371 .platform_data = &sx150x_epmdata
4372 },
4373};
4374#endif
4375#endif
4376#endif
4377
4378#ifdef CONFIG_SENSORS_MSM_ADC
4379static struct resource resources_adc[] = {
4380 {
4381 .start = PM8058_ADC_IRQ(PM8058_IRQ_BASE),
4382 .end = PM8058_ADC_IRQ(PM8058_IRQ_BASE),
4383 .flags = IORESOURCE_IRQ,
4384 },
4385};
4386
4387static struct adc_access_fn xoadc_fn = {
4388 pm8058_xoadc_select_chan_and_start_conv,
4389 pm8058_xoadc_read_adc_code,
4390 pm8058_xoadc_get_properties,
4391 pm8058_xoadc_slot_request,
4392 pm8058_xoadc_restore_slot,
4393 pm8058_xoadc_calibrate,
4394};
4395
4396#if defined(CONFIG_I2C) && \
4397 (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE))
4398static struct regulator *vreg_adc_epm1;
4399
4400static struct i2c_client *epm_expander_i2c_register_board(void)
4401
4402{
4403 struct i2c_adapter *i2c_adap;
4404 struct i2c_client *client = NULL;
4405 i2c_adap = i2c_get_adapter(0x0);
4406
4407 if (i2c_adap == NULL)
4408 printk(KERN_ERR "\nepm_expander_i2c_adapter is NULL\n");
4409
4410 if (i2c_adap != NULL)
4411 client = i2c_new_device(i2c_adap,
4412 &fluid_expanders_i2c_epm_info[0]);
4413 return client;
4414
4415}
4416
4417static unsigned int msm_adc_gpio_configure_expander_enable(void)
4418{
4419 int rc = 0;
4420 static struct i2c_client *epm_i2c_client;
4421
4422 printk(KERN_DEBUG "Enter msm_adc_gpio_configure_expander_enable\n");
4423
4424 vreg_adc_epm1 = regulator_get(NULL, "8058_s3");
4425
4426 if (IS_ERR(vreg_adc_epm1)) {
4427 printk(KERN_ERR "%s: Unable to get 8058_s3\n", __func__);
4428 return 0;
4429 }
4430
4431 rc = regulator_set_voltage(vreg_adc_epm1, 1800000, 1800000);
4432 if (rc)
4433 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable: "
4434 "regulator set voltage failed\n");
4435
4436 rc = regulator_enable(vreg_adc_epm1);
4437 if (rc) {
4438 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable: "
4439 "Error while enabling regulator for epm s3 %d\n", rc);
4440 return rc;
4441 }
4442
4443 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_enable: Start"
4444 " setting the value of the EPM 3.3, 5v and lvlsft\n");
4445
4446 msleep(1000);
4447
4448 rc = gpio_request(GPIO_EPM_5V_BOOST_EN, "boost_epm_5v");
4449 if (!rc) {
4450 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_enable: "
4451 "Configure 5v boost\n");
4452 gpio_direction_output(GPIO_EPM_5V_BOOST_EN, 1);
4453 } else {
4454 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable: "
4455 "Error for epm 5v boost en\n");
4456 goto exit_vreg_epm;
4457 }
4458
4459 msleep(500);
4460
4461 rc = gpio_request(GPIO_EPM_3_3V_EN, "epm_3_3v");
4462 if (!rc) {
4463 gpio_direction_output(GPIO_EPM_3_3V_EN, 1);
4464 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_enable: "
4465 "Configure epm 3.3v\n");
4466 } else {
4467 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable: "
4468 "Error for gpio 3.3ven\n");
4469 goto exit_vreg_epm;
4470 }
4471 msleep(500);
4472
4473 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_enable: "
4474 "Trying to request EPM LVLSFT_EN\n");
4475 rc = gpio_request(GPIO_EPM_LVLSFT_EN, "lvsft_en");
4476 if (!rc) {
4477 gpio_direction_output(GPIO_EPM_LVLSFT_EN, 1);
4478 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_enable: "
4479 "Configure the lvlsft\n");
4480 } else {
4481 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable: "
4482 "Error for epm lvlsft_en\n");
4483 goto exit_vreg_epm;
4484 }
4485
4486 msleep(500);
4487
4488 if (!epm_i2c_client)
4489 epm_i2c_client = epm_expander_i2c_register_board();
4490
4491 rc = gpio_request(GPIO_PWR_MON_ENABLE, "pwr_mon_enable");
4492 if (!rc)
4493 rc = gpio_direction_output(GPIO_PWR_MON_ENABLE, 1);
4494 if (rc) {
4495 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4496 ": GPIO PWR MON Enable issue\n");
4497 goto exit_vreg_epm;
4498 }
4499
4500 msleep(1000);
4501
4502 rc = gpio_request(GPIO_ADC1_PWDN_N, "adc1_pwdn");
4503 if (!rc) {
4504 rc = gpio_direction_output(GPIO_ADC1_PWDN_N, 1);
4505 if (rc) {
4506 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4507 ": ADC1_PWDN error direction out\n");
4508 goto exit_vreg_epm;
4509 }
4510 }
4511
4512 msleep(100);
4513
4514 rc = gpio_request(GPIO_ADC2_PWDN_N, "adc2_pwdn");
4515 if (!rc) {
4516 rc = gpio_direction_output(GPIO_ADC2_PWDN_N, 1);
4517 if (rc) {
4518 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4519 ": ADC2_PWD error direction out\n");
4520 goto exit_vreg_epm;
4521 }
4522 }
4523
4524 msleep(1000);
4525
4526 rc = gpio_request(GPIO_PWR_MON_START, "pwr_mon_start");
4527 if (!rc) {
4528 rc = gpio_direction_output(GPIO_PWR_MON_START, 0);
4529 if (rc) {
4530 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4531 "Gpio request problem %d\n", rc);
4532 goto exit_vreg_epm;
4533 }
4534 }
4535
4536 rc = gpio_request(GPIO_EPM_SPI_ADC1_CS_N, "spi_adc1_cs");
4537 if (!rc) {
4538 rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
4539 if (rc) {
4540 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4541 ": EPM_SPI_ADC1_CS_N error\n");
4542 goto exit_vreg_epm;
4543 }
4544 }
4545
4546 rc = gpio_request(GPIO_EPM_SPI_ADC2_CS_N, "spi_adc2_cs");
4547 if (!rc) {
4548 rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 0);
4549 if (rc) {
4550 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4551 ": EPM_SPI_ADC2_Cs_N error\n");
4552 goto exit_vreg_epm;
4553 }
4554 }
4555
4556 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_enable: Set "
4557 "the power monitor reset for epm\n");
4558
4559 rc = gpio_request(GPIO_PWR_MON_RESET_N, "pwr_mon_reset_n");
4560 if (!rc) {
4561 gpio_direction_output(GPIO_PWR_MON_RESET_N, 0);
4562 if (rc) {
4563 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable"
4564 ": Error in the power mon reset\n");
4565 goto exit_vreg_epm;
4566 }
4567 }
4568
4569 msleep(1000);
4570
4571 gpio_set_value_cansleep(GPIO_PWR_MON_RESET_N, 1);
4572
4573 msleep(500);
4574
4575 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC1_CS_N, 1);
4576
4577 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC2_CS_N, 1);
4578
4579 return rc;
4580
4581exit_vreg_epm:
4582 regulator_disable(vreg_adc_epm1);
4583
4584 printk(KERN_ERR "msm_adc_gpio_configure_expander_enable: Exit."
4585 " rc = %d.\n", rc);
4586 return rc;
4587};
4588
4589static unsigned int msm_adc_gpio_configure_expander_disable(void)
4590{
4591 int rc = 0;
4592
4593 gpio_set_value_cansleep(GPIO_PWR_MON_RESET_N, 0);
4594 gpio_free(GPIO_PWR_MON_RESET_N);
4595
4596 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC1_CS_N, 0);
4597 gpio_free(GPIO_EPM_SPI_ADC1_CS_N);
4598
4599 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC2_CS_N, 0);
4600 gpio_free(GPIO_EPM_SPI_ADC2_CS_N);
4601
4602 gpio_set_value_cansleep(GPIO_PWR_MON_START, 0);
4603 gpio_free(GPIO_PWR_MON_START);
4604
4605 gpio_direction_output(GPIO_ADC1_PWDN_N, 0);
4606 gpio_free(GPIO_ADC1_PWDN_N);
4607
4608 gpio_direction_output(GPIO_ADC2_PWDN_N, 0);
4609 gpio_free(GPIO_ADC2_PWDN_N);
4610
4611 gpio_set_value_cansleep(GPIO_PWR_MON_ENABLE, 0);
4612 gpio_free(GPIO_PWR_MON_ENABLE);
4613
4614 gpio_set_value_cansleep(GPIO_EPM_LVLSFT_EN, 0);
4615 gpio_free(GPIO_EPM_LVLSFT_EN);
4616
4617 gpio_set_value_cansleep(GPIO_EPM_5V_BOOST_EN, 0);
4618 gpio_free(GPIO_EPM_5V_BOOST_EN);
4619
4620 gpio_set_value_cansleep(GPIO_EPM_3_3V_EN, 0);
4621 gpio_free(GPIO_EPM_3_3V_EN);
4622
4623 rc = regulator_disable(vreg_adc_epm1);
4624 if (rc)
4625 printk(KERN_DEBUG "msm_adc_gpio_configure_expander_disable: "
4626 "Error while enabling regulator for epm s3 %d\n", rc);
4627 regulator_put(vreg_adc_epm1);
4628
4629 printk(KERN_DEBUG "Exi msm_adc_gpio_configure_expander_disable\n");
4630 return rc;
4631};
4632
4633unsigned int msm_adc_gpio_expander_enable(int cs_enable)
4634{
4635 int rc = 0;
4636
4637 printk(KERN_DEBUG "msm_adc_gpio_expander_enable: cs_enable = %d",
4638 cs_enable);
4639
4640 if (cs_enable < 16) {
4641 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC1_CS_N, 0);
4642 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC2_CS_N, 1);
4643 } else {
4644 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC2_CS_N, 0);
4645 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC1_CS_N, 1);
4646 }
4647 return rc;
4648};
4649
4650unsigned int msm_adc_gpio_expander_disable(int cs_disable)
4651{
4652 int rc = 0;
4653
4654 printk(KERN_DEBUG "Enter msm_adc_gpio_expander_disable.\n");
4655
4656 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC1_CS_N, 1);
4657
4658 gpio_set_value_cansleep(GPIO_EPM_SPI_ADC2_CS_N, 1);
4659
4660 return rc;
4661};
4662#endif
4663
4664static struct msm_adc_channels msm_adc_channels_data[] = {
4665 {"vbatt", CHANNEL_ADC_VBATT, 0, &xoadc_fn, CHAN_PATH_TYPE2,
4666 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE3, scale_default},
4667 {"vcoin", CHANNEL_ADC_VCOIN, 0, &xoadc_fn, CHAN_PATH_TYPE1,
4668 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_default},
4669 {"vcharger_channel", CHANNEL_ADC_VCHG, 0, &xoadc_fn, CHAN_PATH_TYPE3,
4670 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE4, scale_default},
4671 {"charger_current_monitor", CHANNEL_ADC_CHG_MONITOR, 0, &xoadc_fn,
4672 CHAN_PATH_TYPE4,
4673 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE1, scale_default},
4674 {"vph_pwr", CHANNEL_ADC_VPH_PWR, 0, &xoadc_fn, CHAN_PATH_TYPE5,
4675 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE3, scale_default},
4676 {"usb_vbus", CHANNEL_ADC_USB_VBUS, 0, &xoadc_fn, CHAN_PATH_TYPE11,
4677 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE3, scale_default},
4678 {"pmic_therm", CHANNEL_ADC_DIE_TEMP, 0, &xoadc_fn, CHAN_PATH_TYPE12,
4679 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE1, scale_pmic_therm},
4680 {"pmic_therm_4K", CHANNEL_ADC_DIE_TEMP_4K, 0, &xoadc_fn,
4681 CHAN_PATH_TYPE12,
4682 ADC_CONFIG_TYPE1, ADC_CALIB_CONFIG_TYPE7, scale_pmic_therm},
4683 {"xo_therm", CHANNEL_ADC_XOTHERM, 0, &xoadc_fn, CHAN_PATH_TYPE_NONE,
4684 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE5, tdkntcgtherm},
4685 {"xo_therm_4K", CHANNEL_ADC_XOTHERM_4K, 0, &xoadc_fn,
4686 CHAN_PATH_TYPE_NONE,
4687 ADC_CONFIG_TYPE1, ADC_CALIB_CONFIG_TYPE6, tdkntcgtherm},
4688 {"hdset_detect", CHANNEL_ADC_HDSET, 0, &xoadc_fn, CHAN_PATH_TYPE6,
4689 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE1, scale_default},
4690 {"chg_batt_amon", CHANNEL_ADC_BATT_AMON, 0, &xoadc_fn, CHAN_PATH_TYPE10,
4691 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE1,
4692 scale_xtern_chgr_cur},
4693 {"msm_therm", CHANNEL_ADC_MSM_THERM, 0, &xoadc_fn, CHAN_PATH_TYPE8,
4694 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_msm_therm},
4695 {"batt_therm", CHANNEL_ADC_BATT_THERM, 0, &xoadc_fn, CHAN_PATH_TYPE7,
4696 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_batt_therm},
4697 {"batt_id", CHANNEL_ADC_BATT_ID, 0, &xoadc_fn, CHAN_PATH_TYPE9,
4698 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_default},
4699 {"ref_625mv", CHANNEL_ADC_625_REF, 0, &xoadc_fn, CHAN_PATH_TYPE15,
4700 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_default},
4701 {"ref_1250mv", CHANNEL_ADC_1250_REF, 0, &xoadc_fn, CHAN_PATH_TYPE13,
4702 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_default},
4703 {"ref_325mv", CHANNEL_ADC_325_REF, 0, &xoadc_fn, CHAN_PATH_TYPE14,
4704 ADC_CONFIG_TYPE2, ADC_CALIB_CONFIG_TYPE2, scale_default},
4705};
4706
4707static char *msm_adc_fluid_device_names[] = {
4708 "ADS_ADC1",
4709 "ADS_ADC2",
4710};
4711
4712static struct msm_adc_platform_data msm_adc_pdata = {
4713 .channel = msm_adc_channels_data,
4714 .num_chan_supported = ARRAY_SIZE(msm_adc_channels_data),
4715#if defined(CONFIG_I2C) && \
4716 (defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE))
4717 .adc_gpio_enable = msm_adc_gpio_expander_enable,
4718 .adc_gpio_disable = msm_adc_gpio_expander_disable,
4719 .adc_fluid_enable = msm_adc_gpio_configure_expander_enable,
4720 .adc_fluid_disable = msm_adc_gpio_configure_expander_disable,
4721#endif
4722};
4723
4724static struct platform_device msm_adc_device = {
4725 .name = "msm_adc",
4726 .id = -1,
4727 .dev = {
4728 .platform_data = &msm_adc_pdata,
4729 },
4730};
4731
4732static void pmic8058_xoadc_mpp_config(void)
4733{
4734 int rc;
4735
4736 rc = pm8901_mpp_config_digital_out(XOADC_MPP_4,
4737 PM8901_MPP_DIG_LEVEL_S4, PM_MPP_DOUT_CTL_LOW);
4738 if (rc)
4739 pr_err("%s: Config mpp4 on pmic 8901 failed\n", __func__);
4740
4741 rc = pm8058_mpp_config_analog_input(XOADC_MPP_3,
4742 PM_MPP_AIN_AMUX_CH5, PM_MPP_AOUT_CTL_DISABLE);
4743 if (rc)
4744 pr_err("%s: Config mpp3 on pmic 8058 failed\n", __func__);
4745
4746 rc = pm8058_mpp_config_analog_input(XOADC_MPP_5,
4747 PM_MPP_AIN_AMUX_CH9, PM_MPP_AOUT_CTL_DISABLE);
4748 if (rc)
4749 pr_err("%s: Config mpp5 on pmic 8058 failed\n", __func__);
4750
4751 rc = pm8058_mpp_config_analog_input(XOADC_MPP_7,
4752 PM_MPP_AIN_AMUX_CH6, PM_MPP_AOUT_CTL_DISABLE);
4753 if (rc)
4754 pr_err("%s: Config mpp7 on pmic 8058 failed\n", __func__);
4755
4756 rc = pm8058_mpp_config_analog_input(XOADC_MPP_8,
4757 PM_MPP_AIN_AMUX_CH8, PM_MPP_AOUT_CTL_DISABLE);
4758 if (rc)
4759 pr_err("%s: Config mpp8 on pmic 8058 failed\n", __func__);
4760
4761 rc = pm8058_mpp_config_analog_input(XOADC_MPP_10,
4762 PM_MPP_AIN_AMUX_CH7, PM_MPP_AOUT_CTL_DISABLE);
4763 if (rc)
4764 pr_err("%s: Config mpp10 on pmic 8058 failed\n", __func__);
4765}
4766
4767static struct regulator *vreg_ldo18_adc;
4768
4769static int pmic8058_xoadc_vreg_config(int on)
4770{
4771 int rc;
4772
4773 if (on) {
4774 rc = regulator_enable(vreg_ldo18_adc);
4775 if (rc)
4776 pr_err("%s: Enable of regulator ldo18_adc "
4777 "failed\n", __func__);
4778 } else {
4779 rc = regulator_disable(vreg_ldo18_adc);
4780 if (rc)
4781 pr_err("%s: Disable of regulator ldo18_adc "
4782 "failed\n", __func__);
4783 }
4784
4785 return rc;
4786}
4787
4788static int pmic8058_xoadc_vreg_setup(void)
4789{
4790 int rc;
4791
4792 vreg_ldo18_adc = regulator_get(NULL, "8058_l18");
4793 if (IS_ERR(vreg_ldo18_adc)) {
4794 printk(KERN_ERR "%s: vreg get failed (%ld)\n",
4795 __func__, PTR_ERR(vreg_ldo18_adc));
4796 rc = PTR_ERR(vreg_ldo18_adc);
4797 goto fail;
4798 }
4799
4800 rc = regulator_set_voltage(vreg_ldo18_adc, 2200000, 2200000);
4801 if (rc) {
4802 pr_err("%s: unable to set ldo18 voltage to 2.2V\n", __func__);
4803 goto fail;
4804 }
4805
4806 return rc;
4807fail:
4808 regulator_put(vreg_ldo18_adc);
4809 return rc;
4810}
4811
4812static void pmic8058_xoadc_vreg_shutdown(void)
4813{
4814 regulator_put(vreg_ldo18_adc);
4815}
4816
4817/* usec. For this ADC,
4818 * this time represents clk rate @ txco w/ 1024 decimation ratio.
4819 * Each channel has different configuration, thus at the time of starting
4820 * the conversion, xoadc will return actual conversion time
4821 * */
4822static struct adc_properties pm8058_xoadc_data = {
4823 .adc_reference = 2200, /* milli-voltage for this adc */
4824 .bitresolution = 15,
4825 .bipolar = 0,
4826 .conversiontime = 54,
4827};
4828
4829static struct xoadc_platform_data xoadc_pdata = {
4830 .xoadc_prop = &pm8058_xoadc_data,
4831 .xoadc_mpp_config = pmic8058_xoadc_mpp_config,
4832 .xoadc_vreg_set = pmic8058_xoadc_vreg_config,
4833 .xoadc_num = XOADC_PMIC_0,
4834 .xoadc_vreg_setup = pmic8058_xoadc_vreg_setup,
4835 .xoadc_vreg_shutdown = pmic8058_xoadc_vreg_shutdown,
4836};
4837#endif
4838
4839#ifdef CONFIG_MSM_SDIO_AL
4840
4841static unsigned mdm2ap_status = 140;
4842
4843static int configure_mdm2ap_status(int on)
4844{
4845 int ret = 0;
4846 if (on)
4847 ret = msm_gpiomux_get(mdm2ap_status);
4848 else
4849 ret = msm_gpiomux_put(mdm2ap_status);
4850
4851 if (ret)
4852 pr_err("%s: mdm2ap_status config failed, on = %d\n", __func__,
4853 on);
4854
4855 return ret;
4856}
4857
4858
4859static int get_mdm2ap_status(void)
4860{
4861 return gpio_get_value(mdm2ap_status);
4862}
4863
4864static struct sdio_al_platform_data sdio_al_pdata = {
4865 .config_mdm2ap_status = configure_mdm2ap_status,
4866 .get_mdm2ap_status = get_mdm2ap_status,
4867 .allow_sdioc_version_major_2 = 0,
Konstantin Dorfmanee2e3082011-08-16 15:12:01 +03004868 .peer_sdioc_version_minor = 0x0202,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004869 .peer_sdioc_version_major = 0x0004,
4870 .peer_sdioc_boot_version_minor = 0x0001,
4871 .peer_sdioc_boot_version_major = 0x0003
4872};
4873
4874struct platform_device msm_device_sdio_al = {
4875 .name = "msm_sdio_al",
4876 .id = -1,
4877 .dev = {
Maya Erez6862b142011-08-22 09:07:07 +03004878 .parent = &msm_charm_modem.dev,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004879 .platform_data = &sdio_al_pdata,
4880 },
4881};
4882
4883#endif /* CONFIG_MSM_SDIO_AL */
4884
Praveen Chidambaram043f4ce2011-08-02 09:37:59 -06004885static struct platform_device msm_rpm_device = {
4886 .name = "msm_rpm",
4887 .id = -1,
4888};
4889
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004890static struct platform_device *charm_devices[] __initdata = {
4891 &msm_charm_modem,
4892#ifdef CONFIG_MSM_SDIO_AL
4893 &msm_device_sdio_al,
4894#endif
Maya Erez6862b142011-08-22 09:07:07 +03004895#ifdef CONFIG_MSM_SDIO_AL
4896 &msm_device_sdio_al,
4897#endif
4898
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004899};
4900
4901static struct platform_device *surf_devices[] __initdata = {
4902 &msm_device_smd,
4903 &msm_device_uart_dm12,
4904#ifdef CONFIG_I2C_QUP
4905 &msm_gsbi3_qup_i2c_device,
4906 &msm_gsbi4_qup_i2c_device,
4907 &msm_gsbi7_qup_i2c_device,
4908 &msm_gsbi8_qup_i2c_device,
4909 &msm_gsbi9_qup_i2c_device,
4910 &msm_gsbi12_qup_i2c_device,
4911#endif
4912#ifdef CONFIG_SERIAL_MSM_HS
4913 &msm_device_uart_dm1,
4914#endif
4915#ifdef CONFIG_I2C_SSBI
4916 &msm_device_ssbi1,
4917 &msm_device_ssbi2,
4918 &msm_device_ssbi3,
4919#endif
4920#if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
4921 &isp1763_device,
4922#endif
4923
4924 &asoc_msm_pcm,
4925 &asoc_msm_dai0,
4926 &asoc_msm_dai1,
4927#if defined (CONFIG_MSM_8x60_VOIP)
4928 &asoc_msm_mvs,
4929 &asoc_mvs_dai0,
4930 &asoc_mvs_dai1,
4931#endif
4932#if defined(CONFIG_USB_GADGET_MSM_72K) || defined(CONFIG_USB_EHCI_HCD)
4933 &msm_device_otg,
4934#endif
4935#ifdef CONFIG_USB_GADGET_MSM_72K
4936 &msm_device_gadget_peripheral,
4937#endif
4938#ifdef CONFIG_USB_G_ANDROID
4939 &android_usb_device,
4940#endif
4941#ifdef CONFIG_BATTERY_MSM
4942 &msm_batt_device,
4943#endif
4944#ifdef CONFIG_ANDROID_PMEM
4945 &android_pmem_device,
4946 &android_pmem_adsp_device,
4947 &android_pmem_audio_device,
4948 &android_pmem_smipool_device,
4949#endif
4950#ifdef CONFIG_MSM_ROTATOR
4951 &msm_rotator_device,
4952#endif
4953 &msm_fb_device,
4954 &msm_kgsl_3d0,
4955 &msm_kgsl_2d0,
4956 &msm_kgsl_2d1,
4957 &lcdc_samsung_panel_device,
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -04004958#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
4959 &lcdc_nt35582_panel_device,
4960#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004961#ifdef CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT
4962 &lcdc_samsung_oled_panel_device,
4963#endif
4964#ifdef CONFIG_FB_MSM_LCDC_AUO_WVGA
4965 &lcdc_auo_wvga_panel_device,
4966#endif
4967#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
4968 &hdmi_msm_device,
4969#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
4970#ifdef CONFIG_FB_MSM_MIPI_DSI
4971 &mipi_dsi_toshiba_panel_device,
4972 &mipi_dsi_novatek_panel_device,
4973#endif
4974#ifdef CONFIG_MSM_CAMERA
4975#ifdef CONFIG_MT9E013
4976 &msm_camera_sensor_mt9e013,
4977#endif
4978#ifdef CONFIG_IMX074
4979 &msm_camera_sensor_imx074,
4980#endif
4981#ifdef CONFIG_WEBCAM_OV7692
4982 &msm_camera_sensor_webcam_ov7692,
4983#endif
4984#ifdef CONFIG_WEBCAM_OV9726
4985 &msm_camera_sensor_webcam_ov9726,
4986#endif
4987#ifdef CONFIG_QS_S5K4E1
4988 &msm_camera_sensor_qs_s5k4e1,
4989#endif
Jilai Wang971f97f2011-07-13 14:25:25 -04004990#ifdef CONFIG_VX6953
4991 &msm_camera_sensor_vx6953,
4992#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07004993#endif
4994#ifdef CONFIG_MSM_GEMINI
4995 &msm_gemini_device,
4996#endif
4997#ifdef CONFIG_MSM_VPE
4998 &msm_vpe_device,
4999#endif
5000
5001#if defined(CONFIG_MSM_RPM_LOG) || defined(CONFIG_MSM_RPM_LOG_MODULE)
5002 &msm_rpm_log_device,
5003#endif
5004#if defined(CONFIG_MSM_RPM_STATS_LOG)
5005 &msm_rpm_stat_device,
5006#endif
5007 &msm_device_vidc,
5008#if (defined(CONFIG_MARIMBA_CORE)) && \
5009 (defined(CONFIG_MSM_BT_POWER) || defined(CONFIG_MSM_BT_POWER_MODULE))
5010 &msm_bt_power_device,
5011#endif
5012#ifdef CONFIG_SENSORS_MSM_ADC
5013 &msm_adc_device,
5014#endif
5015#ifdef CONFIG_PMIC8058
5016 &rpm_vreg_device[RPM_VREG_ID_PM8058_L0],
5017 &rpm_vreg_device[RPM_VREG_ID_PM8058_L1],
5018 &rpm_vreg_device[RPM_VREG_ID_PM8058_L2],
5019 &rpm_vreg_device[RPM_VREG_ID_PM8058_L3],
5020 &rpm_vreg_device[RPM_VREG_ID_PM8058_L4],
5021 &rpm_vreg_device[RPM_VREG_ID_PM8058_L5],
5022 &rpm_vreg_device[RPM_VREG_ID_PM8058_L6],
5023 &rpm_vreg_device[RPM_VREG_ID_PM8058_L7],
5024 &rpm_vreg_device[RPM_VREG_ID_PM8058_L8],
5025 &rpm_vreg_device[RPM_VREG_ID_PM8058_L9],
5026 &rpm_vreg_device[RPM_VREG_ID_PM8058_L10],
5027 &rpm_vreg_device[RPM_VREG_ID_PM8058_L11],
5028 &rpm_vreg_device[RPM_VREG_ID_PM8058_L12],
5029 &rpm_vreg_device[RPM_VREG_ID_PM8058_L13],
5030 &rpm_vreg_device[RPM_VREG_ID_PM8058_L14],
5031 &rpm_vreg_device[RPM_VREG_ID_PM8058_L15],
5032 &rpm_vreg_device[RPM_VREG_ID_PM8058_L16],
5033 &rpm_vreg_device[RPM_VREG_ID_PM8058_L17],
5034 &rpm_vreg_device[RPM_VREG_ID_PM8058_L18],
5035 &rpm_vreg_device[RPM_VREG_ID_PM8058_L19],
5036 &rpm_vreg_device[RPM_VREG_ID_PM8058_L20],
5037 &rpm_vreg_device[RPM_VREG_ID_PM8058_L21],
5038 &rpm_vreg_device[RPM_VREG_ID_PM8058_L22],
5039 &rpm_vreg_device[RPM_VREG_ID_PM8058_L23],
5040 &rpm_vreg_device[RPM_VREG_ID_PM8058_L24],
5041 &rpm_vreg_device[RPM_VREG_ID_PM8058_L25],
5042 &rpm_vreg_device[RPM_VREG_ID_PM8058_S2],
5043 &rpm_vreg_device[RPM_VREG_ID_PM8058_S3],
5044 &rpm_vreg_device[RPM_VREG_ID_PM8058_S4],
5045 &rpm_vreg_device[RPM_VREG_ID_PM8058_LVS0],
5046 &rpm_vreg_device[RPM_VREG_ID_PM8058_LVS1],
5047 &rpm_vreg_device[RPM_VREG_ID_PM8058_NCP],
5048#endif
5049#ifdef CONFIG_PMIC8901
5050 &rpm_vreg_device[RPM_VREG_ID_PM8901_L0],
5051 &rpm_vreg_device[RPM_VREG_ID_PM8901_L1],
5052 &rpm_vreg_device[RPM_VREG_ID_PM8901_L2],
5053 &rpm_vreg_device[RPM_VREG_ID_PM8901_L3],
5054 &rpm_vreg_device[RPM_VREG_ID_PM8901_L4],
5055 &rpm_vreg_device[RPM_VREG_ID_PM8901_L5],
5056 &rpm_vreg_device[RPM_VREG_ID_PM8901_L6],
5057 &rpm_vreg_device[RPM_VREG_ID_PM8901_S2],
5058 &rpm_vreg_device[RPM_VREG_ID_PM8901_S3],
5059 &rpm_vreg_device[RPM_VREG_ID_PM8901_S4],
5060 &rpm_vreg_device[RPM_VREG_ID_PM8901_LVS0],
5061 &rpm_vreg_device[RPM_VREG_ID_PM8901_LVS1],
5062 &rpm_vreg_device[RPM_VREG_ID_PM8901_LVS2],
5063 &rpm_vreg_device[RPM_VREG_ID_PM8901_LVS3],
5064 &rpm_vreg_device[RPM_VREG_ID_PM8901_MVS0],
5065#endif
5066
5067#if defined(CONFIG_CRYPTO_DEV_QCRYPTO) || \
5068 defined(CONFIG_CRYPTO_DEV_QCRYPTO_MODULE)
5069 &qcrypto_device,
5070#endif
5071
5072#if defined(CONFIG_CRYPTO_DEV_QCEDEV) || \
5073 defined(CONFIG_CRYPTO_DEV_QCEDEV_MODULE)
5074 &qcedev_device,
5075#endif
5076
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005077
5078#if defined(CONFIG_TSIF) || defined(CONFIG_TSIF_MODULE)
5079#ifdef CONFIG_MSM_USE_TSIF1
5080 &msm_device_tsif[1],
5081#else
5082 &msm_device_tsif[0],
5083#endif /* CONFIG_MSM_USE_TSIF1 */
5084#endif /* CONFIG_TSIF */
5085
5086#ifdef CONFIG_HW_RANDOM_MSM
5087 &msm_device_rng,
5088#endif
5089
5090 &msm_tsens_device,
Praveen Chidambaram043f4ce2011-08-02 09:37:59 -06005091 &msm_rpm_device,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005092
5093};
5094
5095static struct memtype_reserve msm8x60_reserve_table[] __initdata = {
5096 /* Kernel SMI memory pool for video core, used for firmware */
5097 /* and encoder, decoder scratch buffers */
5098 /* Kernel SMI memory pool should always precede the user space */
5099 /* SMI memory pool, as the video core will use offset address */
5100 /* from the Firmware base */
5101 [MEMTYPE_SMI_KERNEL] = {
5102 .start = KERNEL_SMI_BASE,
5103 .limit = KERNEL_SMI_SIZE,
5104 .size = KERNEL_SMI_SIZE,
5105 .flags = MEMTYPE_FLAGS_FIXED,
5106 },
5107 /* User space SMI memory pool for video core */
5108 /* used for encoder, decoder input & output buffers */
5109 [MEMTYPE_SMI] = {
5110 .start = USER_SMI_BASE,
5111 .limit = USER_SMI_SIZE,
5112 .flags = MEMTYPE_FLAGS_FIXED,
5113 },
5114 [MEMTYPE_EBI0] = {
5115 .flags = MEMTYPE_FLAGS_1M_ALIGN,
5116 },
5117 [MEMTYPE_EBI1] = {
5118 .flags = MEMTYPE_FLAGS_1M_ALIGN,
5119 },
5120};
5121
5122static void __init size_pmem_devices(void)
5123{
5124#ifdef CONFIG_ANDROID_PMEM
5125 android_pmem_adsp_pdata.size = pmem_adsp_size;
5126 android_pmem_smipool_pdata.size = MSM_PMEM_SMIPOOL_SIZE;
5127 android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
5128 android_pmem_pdata.size = pmem_sf_size;
5129#endif
5130}
5131
5132static void __init reserve_memory_for(struct android_pmem_platform_data *p)
5133{
5134 msm8x60_reserve_table[p->memory_type].size += p->size;
5135}
5136
5137static void __init reserve_pmem_memory(void)
5138{
5139#ifdef CONFIG_ANDROID_PMEM
5140 reserve_memory_for(&android_pmem_adsp_pdata);
5141 reserve_memory_for(&android_pmem_smipool_pdata);
5142 reserve_memory_for(&android_pmem_audio_pdata);
5143 reserve_memory_for(&android_pmem_pdata);
5144 msm8x60_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
5145#endif
5146}
5147
5148static void __init msm8x60_calculate_reserve_sizes(void)
5149{
5150 size_pmem_devices();
5151 reserve_pmem_memory();
5152}
5153
5154static int msm8x60_paddr_to_memtype(unsigned int paddr)
5155{
5156 if (paddr >= 0x40000000 && paddr < 0x60000000)
5157 return MEMTYPE_EBI1;
5158 if (paddr >= 0x38000000 && paddr < 0x40000000)
5159 return MEMTYPE_SMI;
5160 return MEMTYPE_NONE;
5161}
5162
5163static struct reserve_info msm8x60_reserve_info __initdata = {
5164 .memtype_reserve_table = msm8x60_reserve_table,
5165 .calculate_reserve_sizes = msm8x60_calculate_reserve_sizes,
5166 .paddr_to_memtype = msm8x60_paddr_to_memtype,
5167};
5168
5169static void __init msm8x60_reserve(void)
5170{
5171 reserve_info = &msm8x60_reserve_info;
5172 msm_reserve();
5173}
5174
5175#define EXT_CHG_VALID_MPP 10
5176#define EXT_CHG_VALID_MPP_2 11
5177
5178#ifdef CONFIG_ISL9519_CHARGER
5179static int isl_detection_setup(void)
5180{
5181 int ret = 0;
5182
5183 ret = pm8058_mpp_config_digital_in(EXT_CHG_VALID_MPP,
5184 PM8058_MPP_DIG_LEVEL_S3,
5185 PM_MPP_DIN_TO_INT);
5186 ret |= pm8058_mpp_config_bi_dir(EXT_CHG_VALID_MPP_2,
5187 PM8058_MPP_DIG_LEVEL_S3,
5188 PM_MPP_BI_PULLUP_10KOHM
5189 );
5190 return ret;
5191}
5192
5193static struct isl_platform_data isl_data __initdata = {
5194 .chgcurrent = 700,
5195 .valid_n_gpio = PM8058_MPP_PM_TO_SYS(10),
5196 .chg_detection_config = isl_detection_setup,
5197 .max_system_voltage = 4200,
5198 .min_system_voltage = 3200,
5199 .term_current = 120,
5200 .input_current = 2048,
5201};
5202
5203static struct i2c_board_info isl_charger_i2c_info[] __initdata = {
5204 {
5205 I2C_BOARD_INFO("isl9519q", 0x9),
5206 .irq = PM8058_CBLPWR_IRQ(PM8058_IRQ_BASE),
5207 .platform_data = &isl_data,
5208 },
5209};
5210#endif
5211
5212#if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
5213static int smb137b_detection_setup(void)
5214{
5215 int ret = 0;
5216
5217 ret = pm8058_mpp_config_digital_in(EXT_CHG_VALID_MPP,
5218 PM8058_MPP_DIG_LEVEL_S3,
5219 PM_MPP_DIN_TO_INT);
5220 ret |= pm8058_mpp_config_bi_dir(EXT_CHG_VALID_MPP_2,
5221 PM8058_MPP_DIG_LEVEL_S3,
5222 PM_MPP_BI_PULLUP_10KOHM);
5223 return ret;
5224}
5225
5226static struct smb137b_platform_data smb137b_data __initdata = {
5227 .chg_detection_config = smb137b_detection_setup,
5228 .valid_n_gpio = PM8058_MPP_PM_TO_SYS(10),
5229 .batt_mah_rating = 950,
5230};
5231
5232static struct i2c_board_info smb137b_charger_i2c_info[] __initdata = {
5233 {
5234 I2C_BOARD_INFO("smb137b", 0x08),
5235 .irq = PM8058_CBLPWR_IRQ(PM8058_IRQ_BASE),
5236 .platform_data = &smb137b_data,
5237 },
5238};
5239#endif
5240
5241#ifdef CONFIG_PMIC8058
5242#define PMIC_GPIO_SDC3_DET 22
5243
5244static int pm8058_gpios_init(void)
5245{
5246 int i;
5247 int rc;
5248 struct pm8058_gpio_cfg {
5249 int gpio;
5250 struct pm8058_gpio cfg;
5251 };
5252
5253 struct pm8058_gpio_cfg gpio_cfgs[] = {
5254 { /* FFA ethernet */
5255 6,
5256 {
5257 .direction = PM_GPIO_DIR_IN,
5258 .pull = PM_GPIO_PULL_DN,
5259 .vin_sel = 2,
5260 .function = PM_GPIO_FUNC_NORMAL,
5261 .inv_int_pol = 0,
5262 },
5263 },
5264#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
5265 {
5266 PMIC_GPIO_SDC3_DET - 1,
5267 {
5268 .direction = PM_GPIO_DIR_IN,
5269 .pull = PM_GPIO_PULL_UP_30,
5270 .vin_sel = 2,
5271 .function = PM_GPIO_FUNC_NORMAL,
5272 .inv_int_pol = 0,
5273 },
5274 },
5275#endif
5276 { /* core&surf gpio expander */
5277 UI_INT1_N,
5278 {
5279 .direction = PM_GPIO_DIR_IN,
5280 .pull = PM_GPIO_PULL_NO,
5281 .vin_sel = PM_GPIO_VIN_S3,
5282 .function = PM_GPIO_FUNC_NORMAL,
5283 .inv_int_pol = 0,
5284 },
5285 },
5286 { /* docking gpio expander */
5287 UI_INT2_N,
5288 {
5289 .direction = PM_GPIO_DIR_IN,
5290 .pull = PM_GPIO_PULL_NO,
5291 .vin_sel = PM_GPIO_VIN_S3,
5292 .function = PM_GPIO_FUNC_NORMAL,
5293 .inv_int_pol = 0,
5294 },
5295 },
5296 { /* FHA/keypad gpio expanders */
5297 UI_INT3_N,
5298 {
5299 .direction = PM_GPIO_DIR_IN,
5300 .pull = PM_GPIO_PULL_NO,
5301 .vin_sel = PM_GPIO_VIN_S3,
5302 .function = PM_GPIO_FUNC_NORMAL,
5303 .inv_int_pol = 0,
5304 },
5305 },
5306 { /* TouchDisc Interrupt */
5307 5,
5308 {
5309 .direction = PM_GPIO_DIR_IN,
5310 .pull = PM_GPIO_PULL_UP_1P5,
5311 .vin_sel = 2,
5312 .function = PM_GPIO_FUNC_NORMAL,
5313 .inv_int_pol = 0,
5314 }
5315 },
5316 { /* Timpani Reset */
5317 20,
5318 {
5319 .direction = PM_GPIO_DIR_OUT,
5320 .output_value = 1,
5321 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
5322 .pull = PM_GPIO_PULL_DN,
5323 .out_strength = PM_GPIO_STRENGTH_HIGH,
5324 .function = PM_GPIO_FUNC_NORMAL,
5325 .vin_sel = 2,
5326 .inv_int_pol = 0,
5327 }
5328 },
5329 { /* PMIC ID interrupt */
5330 36,
5331 {
5332 .direction = PM_GPIO_DIR_IN,
5333 .pull = PM_GPIO_PULL_UP_1P5,
5334 .function = PM_GPIO_FUNC_NORMAL,
5335 .vin_sel = 2,
5336 .inv_int_pol = 0,
5337 }
5338 },
5339 };
5340
5341#if defined(CONFIG_HAPTIC_ISA1200) || \
5342 defined(CONFIG_HAPTIC_ISA1200_MODULE)
5343
5344 struct pm8058_gpio_cfg en_hap_gpio_cfg = {
5345 PMIC_GPIO_HAP_ENABLE,
5346 {
5347 .direction = PM_GPIO_DIR_OUT,
5348 .pull = PM_GPIO_PULL_NO,
5349 .out_strength = PM_GPIO_STRENGTH_HIGH,
5350 .function = PM_GPIO_FUNC_NORMAL,
5351 .inv_int_pol = 0,
5352 .vin_sel = 2,
5353 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
5354 .output_value = 0,
5355 }
5356
5357 };
5358#endif
5359
5360#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
5361 struct pm8058_gpio_cfg line_in_gpio_cfg = {
5362 18,
5363 {
5364 .direction = PM_GPIO_DIR_IN,
5365 .pull = PM_GPIO_PULL_UP_1P5,
5366 .vin_sel = 2,
5367 .function = PM_GPIO_FUNC_NORMAL,
5368 .inv_int_pol = 0,
5369 }
5370 };
5371#endif
5372
5373#if defined(CONFIG_QS_S5K4E1)
5374 {
5375 struct pm8058_gpio_cfg qs_hc37_cam_pd_gpio_cfg = {
5376 26,
5377 {
5378 .direction = PM_GPIO_DIR_OUT,
5379 .output_value = 0,
5380 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
5381 .pull = PM_GPIO_PULL_DN,
5382 .out_strength = PM_GPIO_STRENGTH_HIGH,
5383 .function = PM_GPIO_FUNC_NORMAL,
5384 .vin_sel = 2,
5385 .inv_int_pol = 0,
5386 }
5387 };
5388#endif
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -04005389#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
5390 struct pm8058_gpio_cfg pmic_lcdc_nt35582_gpio_cfg = {
5391 GPIO_NT35582_BL_EN_HW_PIN - 1,
5392 {
5393 .direction = PM_GPIO_DIR_OUT,
5394 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
5395 .output_value = 1,
5396 .pull = PM_GPIO_PULL_UP_30,
5397 /* 2.9V PM_GPIO_VIN_L2, which gives 2.6V */
5398 .vin_sel = PM_GPIO_VIN_L5,
5399 .out_strength = PM_GPIO_STRENGTH_HIGH,
5400 .function = PM_GPIO_FUNC_NORMAL,
5401 .inv_int_pol = 0,
5402 }
5403 };
5404#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005405#if defined(CONFIG_HAPTIC_ISA1200) || \
5406 defined(CONFIG_HAPTIC_ISA1200_MODULE)
5407 if (machine_is_msm8x60_fluid()) {
5408 rc = pm8058_gpio_config(en_hap_gpio_cfg.gpio,
5409 &en_hap_gpio_cfg.cfg);
5410 if (rc < 0) {
5411 pr_err("%s pmic haptics gpio config failed\n",
5412 __func__);
5413 return rc;
5414 }
5415 }
5416#endif
5417
5418#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
5419 /* Line_in only for 8660 ffa & surf */
5420 if (machine_is_msm8x60_ffa() || machine_is_msm8x60_surf() ||
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04005421 machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005422 machine_is_msm8x60_fusn_ffa()) {
5423 rc = pm8058_gpio_config(line_in_gpio_cfg.gpio,
5424 &line_in_gpio_cfg.cfg);
5425 if (rc < 0) {
5426 pr_err("%s pmic line_in gpio config failed\n",
5427 __func__);
5428 return rc;
5429 }
5430 }
5431#endif
5432
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -04005433#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
5434 if (machine_is_msm8x60_dragon()) {
5435 rc = pm8058_gpio_config(pmic_lcdc_nt35582_gpio_cfg.gpio,
5436 &pmic_lcdc_nt35582_gpio_cfg.cfg);
5437 if (rc < 0) {
5438 pr_err("%s pmic gpio config failed\n", __func__);
5439 return rc;
5440 }
5441 }
5442#endif
5443
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005444#if defined(CONFIG_QS_S5K4E1)
5445 /* qs_cam_hc37_cam_pd only for 8660 fluid qs camera*/
5446 if (machine_is_msm8x60_fluid()) {
5447 rc = pm8058_gpio_config(qs_hc37_cam_pd_gpio_cfg.gpio,
5448 &qs_hc37_cam_pd_gpio_cfg.cfg);
5449 if (rc < 0) {
5450 pr_err("%s pmic qs_hc37_cam_pd gpio config failed\n",
5451 __func__);
5452 return rc;
5453 }
5454 }
5455 }
5456#endif
5457
5458 for (i = 0; i < ARRAY_SIZE(gpio_cfgs); ++i) {
5459 rc = pm8058_gpio_config(gpio_cfgs[i].gpio,
5460 &gpio_cfgs[i].cfg);
5461 if (rc < 0) {
5462 pr_err("%s pmic gpio config failed\n",
5463 __func__);
5464 return rc;
5465 }
5466 }
5467
5468 return 0;
5469}
5470
5471static const unsigned int ffa_keymap[] = {
5472 KEY(0, 0, KEY_FN_F1), /* LS - PUSH1 */
5473 KEY(0, 1, KEY_UP), /* NAV - UP */
5474 KEY(0, 2, KEY_LEFT), /* NAV - LEFT */
5475 KEY(0, 3, KEY_VOLUMEUP), /* Shuttle SW_UP */
5476
5477 KEY(1, 0, KEY_FN_F2), /* LS - PUSH2 */
5478 KEY(1, 1, KEY_RIGHT), /* NAV - RIGHT */
5479 KEY(1, 2, KEY_DOWN), /* NAV - DOWN */
5480 KEY(1, 3, KEY_VOLUMEDOWN),
5481
5482 KEY(2, 3, KEY_ENTER), /* SW_PUSH key */
5483
5484 KEY(4, 0, KEY_CAMERA_FOCUS), /* RS - PUSH1 */
5485 KEY(4, 1, KEY_UP), /* USER_UP */
5486 KEY(4, 2, KEY_LEFT), /* USER_LEFT */
5487 KEY(4, 3, KEY_HOME), /* Right switch: MIC Bd */
5488 KEY(4, 4, KEY_FN_F3), /* Reserved MIC */
5489
5490 KEY(5, 0, KEY_CAMERA), /* RS - PUSH2 */
5491 KEY(5, 1, KEY_RIGHT), /* USER_RIGHT */
5492 KEY(5, 2, KEY_DOWN), /* USER_DOWN */
5493 KEY(5, 3, KEY_BACK), /* Left switch: MIC */
5494 KEY(5, 4, KEY_MENU), /* Center switch: MIC */
5495};
5496
Zhang Chang Ken683be172011-08-10 17:45:34 -04005497static const unsigned int dragon_keymap[] = {
5498 KEY(0, 0, KEY_MENU),
5499 KEY(0, 2, KEY_1),
5500 KEY(0, 3, KEY_4),
5501 KEY(0, 4, KEY_7),
5502
5503 KEY(1, 0, KEY_UP),
5504 KEY(1, 1, KEY_LEFT),
5505 KEY(1, 2, KEY_DOWN),
5506 KEY(1, 3, KEY_5),
5507 KEY(1, 4, KEY_8),
5508
5509 KEY(2, 0, KEY_HOME),
5510 KEY(2, 1, KEY_REPLY),
5511 KEY(2, 2, KEY_2),
5512 KEY(2, 3, KEY_6),
5513 KEY(2, 4, KEY_0),
5514
5515 KEY(3, 0, KEY_VOLUMEUP),
5516 KEY(3, 1, KEY_RIGHT),
5517 KEY(3, 2, KEY_3),
5518 KEY(3, 3, KEY_9),
5519 KEY(3, 4, KEY_SWITCHVIDEOMODE),
5520
5521 KEY(4, 0, KEY_VOLUMEDOWN),
5522 KEY(4, 1, KEY_BACK),
5523 KEY(4, 2, KEY_CAMERA),
5524 KEY(4, 3, KEY_KBDILLUMTOGGLE),
5525};
5526
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005527static struct resource resources_keypad[] = {
5528 {
5529 .start = PM8058_KEYPAD_IRQ(PM8058_IRQ_BASE),
5530 .end = PM8058_KEYPAD_IRQ(PM8058_IRQ_BASE),
5531 .flags = IORESOURCE_IRQ,
5532 },
5533 {
5534 .start = PM8058_KEYSTUCK_IRQ(PM8058_IRQ_BASE),
5535 .end = PM8058_KEYSTUCK_IRQ(PM8058_IRQ_BASE),
5536 .flags = IORESOURCE_IRQ,
5537 },
5538};
5539
5540static struct matrix_keymap_data ffa_keymap_data = {
5541 .keymap_size = ARRAY_SIZE(ffa_keymap),
5542 .keymap = ffa_keymap,
5543};
5544
5545static struct pmic8058_keypad_data ffa_keypad_data = {
5546 .input_name = "ffa-keypad",
5547 .input_phys_device = "ffa-keypad/input0",
5548 .num_rows = 6,
5549 .num_cols = 5,
5550 .rows_gpio_start = 8,
5551 .cols_gpio_start = 0,
5552 .debounce_ms = {8, 10},
5553 .scan_delay_ms = 32,
5554 .row_hold_ns = 91500,
5555 .wakeup = 1,
5556 .keymap_data = &ffa_keymap_data,
5557};
5558
Zhang Chang Ken683be172011-08-10 17:45:34 -04005559static struct matrix_keymap_data dragon_keymap_data = {
5560 .keymap_size = ARRAY_SIZE(dragon_keymap),
5561 .keymap = dragon_keymap,
5562};
5563
5564static struct pmic8058_keypad_data dragon_keypad_data = {
5565 .input_name = "dragon-keypad",
5566 .input_phys_device = "dragon-keypad/input0",
5567 .num_rows = 6,
5568 .num_cols = 5,
5569 .rows_gpio_start = 8,
5570 .cols_gpio_start = 0,
5571 .debounce_ms = {8, 10},
5572 .scan_delay_ms = 32,
5573 .row_hold_ns = 91500,
5574 .wakeup = 1,
5575 .keymap_data = &dragon_keymap_data,
5576};
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005577static const unsigned int fluid_keymap[] = {
5578 KEY(0, 0, KEY_FN_F1), /* LS - PUSH1 */
5579 KEY(0, 1, KEY_UP), /* NAV - UP */
5580 KEY(0, 2, KEY_LEFT), /* NAV - LEFT */
5581 KEY(0, 3, KEY_VOLUMEDOWN), /* Shuttle SW_UP */
5582
5583 KEY(1, 0, KEY_FN_F2), /* LS - PUSH2 */
5584 KEY(1, 1, KEY_RIGHT), /* NAV - RIGHT */
5585 KEY(1, 2, KEY_DOWN), /* NAV - DOWN */
5586 KEY(1, 3, KEY_VOLUMEUP),
5587
5588 KEY(2, 3, KEY_ENTER), /* SW_PUSH key */
5589
5590 KEY(4, 0, KEY_CAMERA_FOCUS), /* RS - PUSH1 */
5591 KEY(4, 1, KEY_UP), /* USER_UP */
5592 KEY(4, 2, KEY_LEFT), /* USER_LEFT */
5593 KEY(4, 3, KEY_HOME), /* Right switch: MIC Bd */
5594 KEY(4, 4, KEY_FN_F3), /* Reserved MIC */
5595
Jilai Wang9a895102011-07-12 14:00:35 -04005596 KEY(5, 0, KEY_CAMERA), /* RS - PUSH2 */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07005597 KEY(5, 1, KEY_RIGHT), /* USER_RIGHT */
5598 KEY(5, 2, KEY_DOWN), /* USER_DOWN */
5599 KEY(5, 3, KEY_BACK), /* Left switch: MIC */
5600 KEY(5, 4, KEY_MENU), /* Center switch: MIC */
5601};
5602
5603static struct matrix_keymap_data fluid_keymap_data = {
5604 .keymap_size = ARRAY_SIZE(fluid_keymap),
5605 .keymap = fluid_keymap,
5606};
5607
5608static struct pmic8058_keypad_data fluid_keypad_data = {
5609 .input_name = "fluid-keypad",
5610 .input_phys_device = "fluid-keypad/input0",
5611 .num_rows = 6,
5612 .num_cols = 5,
5613 .rows_gpio_start = 8,
5614 .cols_gpio_start = 0,
5615 .debounce_ms = {8, 10},
5616 .scan_delay_ms = 32,
5617 .row_hold_ns = 91500,
5618 .wakeup = 1,
5619 .keymap_data = &fluid_keymap_data,
5620};
5621
5622static struct resource resources_pwrkey[] = {
5623 {
5624 .start = PM8058_PWRKEY_REL_IRQ(PM8058_IRQ_BASE),
5625 .end = PM8058_PWRKEY_REL_IRQ(PM8058_IRQ_BASE),
5626 .flags = IORESOURCE_IRQ,
5627 },
5628 {
5629 .start = PM8058_PWRKEY_PRESS_IRQ(PM8058_IRQ_BASE),
5630 .end = PM8058_PWRKEY_PRESS_IRQ(PM8058_IRQ_BASE),
5631 .flags = IORESOURCE_IRQ,
5632 },
5633};
5634
5635static struct pmic8058_pwrkey_pdata pwrkey_pdata = {
5636 .pull_up = 1,
5637 .kpd_trigger_delay_us = 970,
5638 .wakeup = 1,
5639 .pwrkey_time_ms = 500,
5640};
5641
5642static struct pmic8058_vibrator_pdata pmic_vib_pdata = {
5643 .initial_vibrate_ms = 500,
5644 .level_mV = 3000,
5645 .max_timeout_ms = 15000,
5646};
5647
5648#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
5649#define PM8058_OTHC_CNTR_BASE0 0xA0
5650#define PM8058_OTHC_CNTR_BASE1 0x134
5651#define PM8058_OTHC_CNTR_BASE2 0x137
5652#define PM8058_LINE_IN_DET_GPIO PM8058_GPIO_PM_TO_SYS(18)
5653
5654static struct othc_accessory_info othc_accessories[] = {
5655 {
5656 .accessory = OTHC_SVIDEO_OUT,
5657 .detect_flags = OTHC_MICBIAS_DETECT | OTHC_SWITCH_DETECT
5658 | OTHC_ADC_DETECT,
5659 .key_code = SW_VIDEOOUT_INSERT,
5660 .enabled = false,
5661 .adc_thres = {
5662 .min_threshold = 20,
5663 .max_threshold = 40,
5664 },
5665 },
5666 {
5667 .accessory = OTHC_ANC_HEADPHONE,
5668 .detect_flags = OTHC_MICBIAS_DETECT | OTHC_GPIO_DETECT |
5669 OTHC_SWITCH_DETECT,
5670 .gpio = PM8058_LINE_IN_DET_GPIO,
5671 .active_low = 1,
5672 .key_code = SW_HEADPHONE_INSERT,
5673 .enabled = true,
5674 },
5675 {
5676 .accessory = OTHC_ANC_HEADSET,
5677 .detect_flags = OTHC_MICBIAS_DETECT | OTHC_GPIO_DETECT,
5678 .gpio = PM8058_LINE_IN_DET_GPIO,
5679 .active_low = 1,
5680 .key_code = SW_HEADPHONE_INSERT,
5681 .enabled = true,
5682 },
5683 {
5684 .accessory = OTHC_HEADPHONE,
5685 .detect_flags = OTHC_MICBIAS_DETECT | OTHC_SWITCH_DETECT,
5686 .key_code = SW_HEADPHONE_INSERT,
5687 .enabled = true,
5688 },
5689 {
5690 .accessory = OTHC_MICROPHONE,
5691 .detect_flags = OTHC_GPIO_DETECT,
5692 .gpio = PM8058_LINE_IN_DET_GPIO,
5693 .active_low = 1,
5694 .key_code = SW_MICROPHONE_INSERT,
5695 .enabled = true,
5696 },
5697 {
5698 .accessory = OTHC_HEADSET,
5699 .detect_flags = OTHC_MICBIAS_DETECT,
5700 .key_code = SW_HEADPHONE_INSERT,
5701 .enabled = true,
5702 },
5703};
5704
5705static struct othc_switch_info switch_info[] = {
5706 {
5707 .min_adc_threshold = 0,
5708 .max_adc_threshold = 100,
5709 .key_code = KEY_PLAYPAUSE,
5710 },
5711 {
5712 .min_adc_threshold = 100,
5713 .max_adc_threshold = 200,
5714 .key_code = KEY_REWIND,
5715 },
5716 {
5717 .min_adc_threshold = 200,
5718 .max_adc_threshold = 500,
5719 .key_code = KEY_FASTFORWARD,
5720 },
5721};
5722
5723static struct othc_n_switch_config switch_config = {
5724 .voltage_settling_time_ms = 0,
5725 .num_adc_samples = 3,
5726 .adc_channel = CHANNEL_ADC_HDSET,
5727 .switch_info = switch_info,
5728 .num_keys = ARRAY_SIZE(switch_info),
5729 .default_sw_en = true,
5730 .default_sw_idx = 0,
5731};
5732
5733static struct hsed_bias_config hsed_bias_config = {
5734 /* HSED mic bias config info */
5735 .othc_headset = OTHC_HEADSET_NO,
5736 .othc_lowcurr_thresh_uA = 100,
5737 .othc_highcurr_thresh_uA = 600,
5738 .othc_hyst_prediv_us = 7800,
5739 .othc_period_clkdiv_us = 62500,
5740 .othc_hyst_clk_us = 121000,
5741 .othc_period_clk_us = 312500,
5742 .othc_wakeup = 1,
5743};
5744
5745static struct othc_hsed_config hsed_config_1 = {
5746 .hsed_bias_config = &hsed_bias_config,
5747 /*
5748 * The detection delay and switch reporting delay are
5749 * required to encounter a hardware bug (spurious switch
5750 * interrupts on slow insertion/removal of the headset).
5751 * This will introduce a delay in reporting the accessory
5752 * insertion and removal to the userspace.
5753 */
5754 .detection_delay_ms = 1500,
5755 /* Switch info */
5756 .switch_debounce_ms = 1500,
5757 .othc_support_n_switch = false,
5758 .switch_config = &switch_config,
5759 .ir_gpio = -1,
5760 /* Accessory info */
5761 .accessories_support = true,
5762 .accessories = othc_accessories,
5763 .othc_num_accessories = ARRAY_SIZE(othc_accessories),
5764};
5765
5766static struct othc_regulator_config othc_reg = {
5767 .regulator = "8058_l5",
5768 .max_uV = 2850000,
5769 .min_uV = 2850000,
5770};
5771
5772/* MIC_BIAS0 is configured as normal MIC BIAS */
5773static struct pmic8058_othc_config_pdata othc_config_pdata_0 = {
5774 .micbias_select = OTHC_MICBIAS_0,
5775 .micbias_capability = OTHC_MICBIAS,
5776 .micbias_enable = OTHC_SIGNAL_OFF,
5777 .micbias_regulator = &othc_reg,
5778};
5779
5780/* MIC_BIAS1 is configured as HSED_BIAS for OTHC */
5781static struct pmic8058_othc_config_pdata othc_config_pdata_1 = {
5782 .micbias_select = OTHC_MICBIAS_1,
5783 .micbias_capability = OTHC_MICBIAS_HSED,
5784 .micbias_enable = OTHC_SIGNAL_PWM_TCXO,
5785 .micbias_regulator = &othc_reg,
5786 .hsed_config = &hsed_config_1,
5787 .hsed_name = "8660_handset",
5788};
5789
5790/* MIC_BIAS2 is configured as normal MIC BIAS */
5791static struct pmic8058_othc_config_pdata othc_config_pdata_2 = {
5792 .micbias_select = OTHC_MICBIAS_2,
5793 .micbias_capability = OTHC_MICBIAS,
5794 .micbias_enable = OTHC_SIGNAL_OFF,
5795 .micbias_regulator = &othc_reg,
5796};
5797
5798static struct resource resources_othc_0[] = {
5799 {
5800 .name = "othc_base",
5801 .start = PM8058_OTHC_CNTR_BASE0,
5802 .end = PM8058_OTHC_CNTR_BASE0,
5803 .flags = IORESOURCE_IO,
5804 },
5805};
5806
5807static struct resource resources_othc_1[] = {
5808 {
5809 .start = PM8058_SW_1_IRQ(PM8058_IRQ_BASE),
5810 .end = PM8058_SW_1_IRQ(PM8058_IRQ_BASE),
5811 .flags = IORESOURCE_IRQ,
5812 },
5813 {
5814 .start = PM8058_IR_1_IRQ(PM8058_IRQ_BASE),
5815 .end = PM8058_IR_1_IRQ(PM8058_IRQ_BASE),
5816 .flags = IORESOURCE_IRQ,
5817 },
5818 {
5819 .name = "othc_base",
5820 .start = PM8058_OTHC_CNTR_BASE1,
5821 .end = PM8058_OTHC_CNTR_BASE1,
5822 .flags = IORESOURCE_IO,
5823 },
5824};
5825
5826static struct resource resources_othc_2[] = {
5827 {
5828 .name = "othc_base",
5829 .start = PM8058_OTHC_CNTR_BASE2,
5830 .end = PM8058_OTHC_CNTR_BASE2,
5831 .flags = IORESOURCE_IO,
5832 },
5833};
5834
5835static void __init msm8x60_init_pm8058_othc(void)
5836{
5837 int i;
5838
5839 if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2 ||
5840 machine_is_msm8x60_fluid() || machine_is_msm8x60_fusion() ||
5841 machine_is_msm8x60_fusn_ffa()) {
5842 /* 3-switch headset supported only by V2 FFA and FLUID */
5843 hsed_config_1.accessories_adc_support = true,
5844 /* ADC based accessory detection works only on V2 and FLUID */
5845 hsed_config_1.accessories_adc_channel = CHANNEL_ADC_HDSET,
5846 hsed_config_1.othc_support_n_switch = true;
5847 }
5848
5849 /* IR GPIO is absent on FLUID */
5850 if (machine_is_msm8x60_fluid())
5851 hsed_config_1.ir_gpio = -1;
5852
5853 for (i = 0; i < ARRAY_SIZE(othc_accessories); i++) {
5854 if (machine_is_msm8x60_fluid()) {
5855 switch (othc_accessories[i].accessory) {
5856 case OTHC_ANC_HEADPHONE:
5857 case OTHC_ANC_HEADSET:
5858 othc_accessories[i].gpio = GPIO_HEADSET_DET_N;
5859 break;
5860 case OTHC_MICROPHONE:
5861 othc_accessories[i].enabled = false;
5862 break;
5863 case OTHC_SVIDEO_OUT:
5864 othc_accessories[i].enabled = true;
5865 hsed_config_1.video_out_gpio = GPIO_HS_SW_DIR;
5866 break;
5867 }
5868 }
5869 }
5870}
5871#endif
5872
5873static struct resource resources_pm8058_charger[] = {
5874 { .name = "CHGVAL",
5875 .start = PM8058_CHGVAL_IRQ(PM8058_IRQ_BASE),
5876 .end = PM8058_CHGVAL_IRQ(PM8058_IRQ_BASE),
5877 .flags = IORESOURCE_IRQ,
5878 },
5879 { .name = "CHGINVAL",
5880 .start = PM8058_CHGINVAL_IRQ(PM8058_IRQ_BASE),
5881 .end = PM8058_CHGINVAL_IRQ(PM8058_IRQ_BASE),
5882 .flags = IORESOURCE_IRQ,
5883 },
5884 {
5885 .name = "CHGILIM",
5886 .start = PM8058_CHGILIM_IRQ(PM8058_IRQ_BASE),
5887 .end = PM8058_CHGILIM_IRQ(PM8058_IRQ_BASE),
5888 .flags = IORESOURCE_IRQ,
5889 },
5890 {
5891 .name = "VCP",
5892 .start = PM8058_VCP_IRQ(PM8058_IRQ_BASE),
5893 .end = PM8058_VCP_IRQ(PM8058_IRQ_BASE),
5894 .flags = IORESOURCE_IRQ,
5895 },
5896 {
5897 .name = "ATC_DONE",
5898 .start = PM8058_ATC_DONE_IRQ(PM8058_IRQ_BASE),
5899 .end = PM8058_ATC_DONE_IRQ(PM8058_IRQ_BASE),
5900 .flags = IORESOURCE_IRQ,
5901 },
5902 {
5903 .name = "ATCFAIL",
5904 .start = PM8058_ATCFAIL_IRQ(PM8058_IRQ_BASE),
5905 .end = PM8058_ATCFAIL_IRQ(PM8058_IRQ_BASE),
5906 .flags = IORESOURCE_IRQ,
5907 },
5908 {
5909 .name = "AUTO_CHGDONE",
5910 .start = PM8058_AUTO_CHGDONE_IRQ(PM8058_IRQ_BASE),
5911 .end = PM8058_AUTO_CHGDONE_IRQ(PM8058_IRQ_BASE),
5912 .flags = IORESOURCE_IRQ,
5913 },
5914 {
5915 .name = "AUTO_CHGFAIL",
5916 .start = PM8058_AUTO_CHGFAIL_IRQ(PM8058_IRQ_BASE),
5917 .end = PM8058_AUTO_CHGFAIL_IRQ(PM8058_IRQ_BASE),
5918 .flags = IORESOURCE_IRQ,
5919 },
5920 {
5921 .name = "CHGSTATE",
5922 .start = PM8058_CHGSTATE_IRQ(PM8058_IRQ_BASE),
5923 .end = PM8058_CHGSTATE_IRQ(PM8058_IRQ_BASE),
5924 .flags = IORESOURCE_IRQ,
5925 },
5926 {
5927 .name = "FASTCHG",
5928 .start = PM8058_FASTCHG_IRQ(PM8058_IRQ_BASE),
5929 .end = PM8058_FASTCHG_IRQ(PM8058_IRQ_BASE),
5930 .flags = IORESOURCE_IRQ,
5931 },
5932 {
5933 .name = "CHG_END",
5934 .start = PM8058_CHG_END_IRQ(PM8058_IRQ_BASE),
5935 .end = PM8058_CHG_END_IRQ(PM8058_IRQ_BASE),
5936 .flags = IORESOURCE_IRQ,
5937 },
5938 {
5939 .name = "BATTTEMP",
5940 .start = PM8058_BATTTEMP_IRQ(PM8058_IRQ_BASE),
5941 .end = PM8058_BATTTEMP_IRQ(PM8058_IRQ_BASE),
5942 .flags = IORESOURCE_IRQ,
5943 },
5944 {
5945 .name = "CHGHOT",
5946 .start = PM8058_CHGHOT_IRQ(PM8058_IRQ_BASE),
5947 .end = PM8058_CHGHOT_IRQ(PM8058_IRQ_BASE),
5948 .flags = IORESOURCE_IRQ,
5949 },
5950 {
5951 .name = "CHGTLIMIT",
5952 .start = PM8058_CHGTLIMIT_IRQ(PM8058_IRQ_BASE),
5953 .end = PM8058_CHGTLIMIT_IRQ(PM8058_IRQ_BASE),
5954 .flags = IORESOURCE_IRQ,
5955 },
5956 {
5957 .name = "CHG_GONE",
5958 .start = PM8058_CHG_GONE_IRQ(PM8058_IRQ_BASE),
5959 .end = PM8058_CHG_GONE_IRQ(PM8058_IRQ_BASE),
5960 .flags = IORESOURCE_IRQ,
5961 },
5962 {
5963 .name = "VCPMAJOR",
5964 .start = PM8058_VCPMAJOR_IRQ(PM8058_IRQ_BASE),
5965 .end = PM8058_VCPMAJOR_IRQ(PM8058_IRQ_BASE),
5966 .flags = IORESOURCE_IRQ,
5967 },
5968 {
5969 .name = "VBATDET",
5970 .start = PM8058_VBATDET_IRQ(PM8058_IRQ_BASE),
5971 .end = PM8058_VBATDET_IRQ(PM8058_IRQ_BASE),
5972 .flags = IORESOURCE_IRQ,
5973 },
5974 {
5975 .name = "BATFET",
5976 .start = PM8058_BATFET_IRQ(PM8058_IRQ_BASE),
5977 .end = PM8058_BATFET_IRQ(PM8058_IRQ_BASE),
5978 .flags = IORESOURCE_IRQ,
5979 },
5980 {
5981 .name = "BATT_REPLACE",
5982 .start = PM8058_BATT_REPLACE_IRQ(PM8058_IRQ_BASE),
5983 .end = PM8058_BATT_REPLACE_IRQ(PM8058_IRQ_BASE),
5984 .flags = IORESOURCE_IRQ,
5985 },
5986 {
5987 .name = "BATTCONNECT",
5988 .start = PM8058_BATTCONNECT_IRQ(PM8058_IRQ_BASE),
5989 .end = PM8058_BATTCONNECT_IRQ(PM8058_IRQ_BASE),
5990 .flags = IORESOURCE_IRQ,
5991 },
5992 {
5993 .name = "VBATDET_LOW",
5994 .start = PM8058_VBATDET_LOW_IRQ(PM8058_IRQ_BASE),
5995 .end = PM8058_VBATDET_LOW_IRQ(PM8058_IRQ_BASE),
5996 .flags = IORESOURCE_IRQ,
5997 },
5998};
5999
6000static int pm8058_pwm_config(struct pwm_device *pwm, int ch, int on)
6001{
6002 struct pm8058_gpio pwm_gpio_config = {
6003 .direction = PM_GPIO_DIR_OUT,
6004 .output_buffer = PM_GPIO_OUT_BUF_CMOS,
6005 .output_value = 0,
6006 .pull = PM_GPIO_PULL_NO,
6007 .vin_sel = PM_GPIO_VIN_VPH,
6008 .out_strength = PM_GPIO_STRENGTH_HIGH,
6009 .function = PM_GPIO_FUNC_2,
6010 };
6011
6012 int rc = -EINVAL;
6013 int id, mode, max_mA;
6014
6015 id = mode = max_mA = 0;
6016 switch (ch) {
6017 case 0:
6018 case 1:
6019 case 2:
6020 if (on) {
6021 id = 24 + ch;
6022 rc = pm8058_gpio_config(id - 1, &pwm_gpio_config);
6023 if (rc)
6024 pr_err("%s: pm8058_gpio_config(%d): rc=%d\n",
6025 __func__, id, rc);
6026 }
6027 break;
6028
6029 case 6:
6030 id = PM_PWM_LED_FLASH;
6031 mode = PM_PWM_CONF_PWM1;
6032 max_mA = 300;
6033 break;
6034
6035 case 7:
6036 id = PM_PWM_LED_FLASH1;
6037 mode = PM_PWM_CONF_PWM1;
6038 max_mA = 300;
6039 break;
6040
6041 default:
6042 break;
6043 }
6044
6045 if (ch >= 6 && ch <= 7) {
6046 if (!on) {
6047 mode = PM_PWM_CONF_NONE;
6048 max_mA = 0;
6049 }
6050 rc = pm8058_pwm_config_led(pwm, id, mode, max_mA);
6051 if (rc)
6052 pr_err("%s: pm8058_pwm_config_led(ch=%d): rc=%d\n",
6053 __func__, ch, rc);
6054 }
6055 return rc;
6056
6057}
6058
6059static struct pm8058_pwm_pdata pm8058_pwm_data = {
6060 .config = pm8058_pwm_config,
6061};
6062
6063#define PM8058_GPIO_INT 88
6064
6065static struct pm8058_gpio_platform_data pm8058_gpio_data = {
6066 .gpio_base = PM8058_GPIO_PM_TO_SYS(0),
6067 .irq_base = PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 0),
6068 .init = pm8058_gpios_init,
6069};
6070
6071static struct pm8058_gpio_platform_data pm8058_mpp_data = {
6072 .gpio_base = PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
6073 .irq_base = PM8058_MPP_IRQ(PM8058_IRQ_BASE, 0),
6074};
6075
6076static struct resource resources_rtc[] = {
6077 {
6078 .start = PM8058_RTC_IRQ(PM8058_IRQ_BASE),
6079 .end = PM8058_RTC_IRQ(PM8058_IRQ_BASE),
6080 .flags = IORESOURCE_IRQ,
6081 },
6082 {
6083 .start = PM8058_RTC_ALARM_IRQ(PM8058_IRQ_BASE),
6084 .end = PM8058_RTC_ALARM_IRQ(PM8058_IRQ_BASE),
6085 .flags = IORESOURCE_IRQ,
6086 },
6087};
6088
Ashay Jaiswal4d1ab552011-07-15 11:30:49 +05306089static struct pm8058_rtc_platform_data pm8058_rtc_pdata = {
6090 .rtc_alarm_powerup = false,
6091};
6092
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006093static struct pmic8058_led pmic8058_flash_leds[] = {
6094 [0] = {
6095 .name = "camera:flash0",
6096 .max_brightness = 15,
6097 .id = PMIC8058_ID_FLASH_LED_0,
6098 },
6099 [1] = {
6100 .name = "camera:flash1",
6101 .max_brightness = 15,
6102 .id = PMIC8058_ID_FLASH_LED_1,
6103 },
6104};
6105
6106static struct pmic8058_leds_platform_data pm8058_flash_leds_data = {
6107 .num_leds = ARRAY_SIZE(pmic8058_flash_leds),
6108 .leds = pmic8058_flash_leds,
6109};
6110
Terence Hampsonc0b6dfb2011-07-15 11:07:17 -04006111static struct pmic8058_led pmic8058_dragon_leds[] = {
6112 [0] = {
6113 /* RED */
6114 .name = "led_drv0",
6115 .max_brightness = 15,
6116 .id = PMIC8058_ID_LED_0,
6117 },/* 300 mA flash led0 drv sink */
6118 [1] = {
6119 /* Yellow */
6120 .name = "led_drv1",
6121 .max_brightness = 15,
6122 .id = PMIC8058_ID_LED_1,
6123 },/* 300 mA flash led0 drv sink */
6124 [2] = {
6125 /* Green */
6126 .name = "led_drv2",
6127 .max_brightness = 15,
6128 .id = PMIC8058_ID_LED_2,
6129 },/* 300 mA flash led0 drv sink */
6130 [3] = {
6131 .name = "led_psensor",
6132 .max_brightness = 15,
6133 .id = PMIC8058_ID_LED_KB_LIGHT,
6134 },/* 300 mA flash led0 drv sink */
6135};
6136
6137static struct pmic8058_leds_platform_data pm8058_dragon_leds_data = {
6138 .num_leds = ARRAY_SIZE(pmic8058_dragon_leds),
6139 .leds = pmic8058_dragon_leds,
6140};
6141
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006142static struct pmic8058_led pmic8058_fluid_flash_leds[] = {
6143 [0] = {
6144 .name = "led:drv0",
6145 .max_brightness = 15,
6146 .id = PMIC8058_ID_FLASH_LED_0,
6147 },/* 300 mA flash led0 drv sink */
6148 [1] = {
6149 .name = "led:drv1",
6150 .max_brightness = 15,
6151 .id = PMIC8058_ID_FLASH_LED_1,
6152 },/* 300 mA flash led1 sink */
6153 [2] = {
6154 .name = "led:drv2",
6155 .max_brightness = 20,
6156 .id = PMIC8058_ID_LED_0,
6157 },/* 40 mA led0 sink */
6158 [3] = {
6159 .name = "keypad:drv",
6160 .max_brightness = 15,
6161 .id = PMIC8058_ID_LED_KB_LIGHT,
6162 },/* 300 mA keypad drv sink */
6163};
6164
6165static struct pmic8058_leds_platform_data pm8058_fluid_flash_leds_data = {
6166 .num_leds = ARRAY_SIZE(pmic8058_fluid_flash_leds),
6167 .leds = pmic8058_fluid_flash_leds,
6168};
6169
6170static struct resource resources_temp_alarm[] = {
6171 {
6172 .start = PM8058_TEMP_ALARM_IRQ(PM8058_IRQ_BASE),
6173 .end = PM8058_TEMP_ALARM_IRQ(PM8058_IRQ_BASE),
6174 .flags = IORESOURCE_IRQ,
6175 },
6176};
6177
6178static struct resource resources_pm8058_misc[] = {
6179 {
6180 .start = PM8058_OSCHALT_IRQ(PM8058_IRQ_BASE),
6181 .end = PM8058_OSCHALT_IRQ(PM8058_IRQ_BASE),
6182 .flags = IORESOURCE_IRQ,
6183 },
6184};
6185
6186static struct resource resources_pm8058_batt_alarm[] = {
6187 {
6188 .start = PM8058_BATT_ALARM_IRQ(PM8058_IRQ_BASE),
6189 .end = PM8058_BATT_ALARM_IRQ(PM8058_IRQ_BASE),
6190 .flags = IORESOURCE_IRQ,
6191 },
6192};
6193
6194#define PM8058_SUBDEV_KPD 0
6195#define PM8058_SUBDEV_LED 1
6196#define PM8058_SUBDEV_VIB 2
6197
6198static struct mfd_cell pm8058_subdevs[] = {
6199 {
6200 .name = "pm8058-keypad",
6201 .id = -1,
6202 .num_resources = ARRAY_SIZE(resources_keypad),
6203 .resources = resources_keypad,
6204 },
6205 { .name = "pm8058-led",
6206 .id = -1,
6207 },
6208 {
6209 .name = "pm8058-vib",
6210 .id = -1,
6211 },
6212 { .name = "pm8058-gpio",
6213 .id = -1,
6214 .platform_data = &pm8058_gpio_data,
6215 .pdata_size = sizeof(pm8058_gpio_data),
6216 },
6217 { .name = "pm8058-mpp",
6218 .id = -1,
6219 .platform_data = &pm8058_mpp_data,
6220 .pdata_size = sizeof(pm8058_mpp_data),
6221 },
6222 { .name = "pm8058-pwrkey",
6223 .id = -1,
6224 .resources = resources_pwrkey,
6225 .num_resources = ARRAY_SIZE(resources_pwrkey),
6226 .platform_data = &pwrkey_pdata,
6227 .pdata_size = sizeof(pwrkey_pdata),
6228 },
6229 {
6230 .name = "pm8058-pwm",
6231 .id = -1,
6232 .platform_data = &pm8058_pwm_data,
6233 .pdata_size = sizeof(pm8058_pwm_data),
6234 },
6235#ifdef CONFIG_SENSORS_MSM_ADC
6236 {
6237 .name = "pm8058-xoadc",
6238 .id = -1,
6239 .num_resources = ARRAY_SIZE(resources_adc),
6240 .resources = resources_adc,
6241 .platform_data = &xoadc_pdata,
6242 .pdata_size = sizeof(xoadc_pdata),
6243 },
6244#endif
6245#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
6246 {
6247 .name = "pm8058-othc",
6248 .id = 0,
6249 .platform_data = &othc_config_pdata_0,
6250 .pdata_size = sizeof(othc_config_pdata_0),
6251 .num_resources = ARRAY_SIZE(resources_othc_0),
6252 .resources = resources_othc_0,
6253 },
6254 {
6255 /* OTHC1 module has headset/switch dection */
6256 .name = "pm8058-othc",
6257 .id = 1,
6258 .num_resources = ARRAY_SIZE(resources_othc_1),
6259 .resources = resources_othc_1,
6260 .platform_data = &othc_config_pdata_1,
6261 .pdata_size = sizeof(othc_config_pdata_1),
6262 },
6263 {
6264 .name = "pm8058-othc",
6265 .id = 2,
6266 .platform_data = &othc_config_pdata_2,
6267 .pdata_size = sizeof(othc_config_pdata_2),
6268 .num_resources = ARRAY_SIZE(resources_othc_2),
6269 .resources = resources_othc_2,
6270 },
6271#endif
6272 {
6273 .name = "pm8058-rtc",
6274 .id = -1,
6275 .num_resources = ARRAY_SIZE(resources_rtc),
6276 .resources = resources_rtc,
Ashay Jaiswal4d1ab552011-07-15 11:30:49 +05306277 .platform_data = &pm8058_rtc_pdata,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006278 },
6279 {
6280 .name = "pm8058-tm",
6281 .id = -1,
6282 .num_resources = ARRAY_SIZE(resources_temp_alarm),
6283 .resources = resources_temp_alarm,
6284 },
6285 { .name = "pm8058-upl",
6286 .id = -1,
6287 },
6288 {
6289 .name = "pm8058-misc",
6290 .id = -1,
6291 .num_resources = ARRAY_SIZE(resources_pm8058_misc),
6292 .resources = resources_pm8058_misc,
6293 },
6294 { .name = "pm8058-batt-alarm",
6295 .id = -1,
6296 .num_resources = ARRAY_SIZE(resources_pm8058_batt_alarm),
6297 .resources = resources_pm8058_batt_alarm,
6298 },
6299};
6300
Terence Hampson90508a92011-08-09 10:40:08 -04006301static struct pmic8058_charger_data pmic8058_charger_dragon = {
6302 .max_source_current = 1800,
6303 .charger_type = CHG_TYPE_AC,
6304};
6305
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006306static struct mfd_cell pm8058_charger_sub_dev = {
6307 .name = "pm8058-charger",
6308 .id = -1,
6309 .num_resources = ARRAY_SIZE(resources_pm8058_charger),
6310 .resources = resources_pm8058_charger,
6311};
6312
6313static struct pm8058_platform_data pm8058_platform_data = {
6314 .irq_base = PM8058_IRQ_BASE,
6315
6316 .num_subdevs = ARRAY_SIZE(pm8058_subdevs),
6317 .sub_devices = pm8058_subdevs,
6318 .irq_trigger_flags = IRQF_TRIGGER_LOW,
6319};
6320
6321static struct i2c_board_info pm8058_boardinfo[] __initdata = {
6322 {
6323 I2C_BOARD_INFO("pm8058-core", 0x55),
6324 .irq = MSM_GPIO_TO_INT(PM8058_GPIO_INT),
6325 .platform_data = &pm8058_platform_data,
6326 },
6327};
6328#endif /* CONFIG_PMIC8058 */
6329
6330#if defined(CONFIG_TOUCHDISC_VTD518_SHINETSU) || \
6331 defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
6332#define TDISC_I2C_SLAVE_ADDR 0x67
6333#define PMIC_GPIO_TDISC PM8058_GPIO_PM_TO_SYS(5)
6334#define TDISC_INT PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 5)
6335
6336static const char *vregs_tdisc_name[] = {
6337 "8058_l5",
6338 "8058_s3",
6339};
6340
6341static const int vregs_tdisc_val[] = {
6342 2850000,/* uV */
6343 1800000,
6344};
6345static struct regulator *vregs_tdisc[ARRAY_SIZE(vregs_tdisc_name)];
6346
6347static int tdisc_shinetsu_setup(void)
6348{
6349 int rc, i;
6350
6351 rc = gpio_request(PMIC_GPIO_TDISC, "tdisc_interrupt");
6352 if (rc) {
6353 pr_err("%s: gpio_request failed for PMIC_GPIO_TDISC\n",
6354 __func__);
6355 return rc;
6356 }
6357
6358 rc = gpio_request(GPIO_JOYSTICK_EN, "tdisc_oe");
6359 if (rc) {
6360 pr_err("%s: gpio_request failed for GPIO_JOYSTICK_EN\n",
6361 __func__);
6362 goto fail_gpio_oe;
6363 }
6364
6365 rc = gpio_direction_output(GPIO_JOYSTICK_EN, 1);
6366 if (rc) {
6367 pr_err("%s: gpio_direction_output failed for GPIO_JOYSTICK_EN\n",
6368 __func__);
6369 gpio_free(GPIO_JOYSTICK_EN);
6370 goto fail_gpio_oe;
6371 }
6372
6373 for (i = 0; i < ARRAY_SIZE(vregs_tdisc_name); i++) {
6374 vregs_tdisc[i] = regulator_get(NULL, vregs_tdisc_name[i]);
6375 if (IS_ERR(vregs_tdisc[i])) {
6376 printk(KERN_ERR "%s: regulator get %s failed (%ld)\n",
6377 __func__, vregs_tdisc_name[i],
6378 PTR_ERR(vregs_tdisc[i]));
6379 rc = PTR_ERR(vregs_tdisc[i]);
6380 goto vreg_get_fail;
6381 }
6382
6383 rc = regulator_set_voltage(vregs_tdisc[i],
6384 vregs_tdisc_val[i], vregs_tdisc_val[i]);
6385 if (rc) {
6386 printk(KERN_ERR "%s: regulator_set_voltage() = %d\n",
6387 __func__, rc);
6388 goto vreg_set_voltage_fail;
6389 }
6390 }
6391
6392 return rc;
6393vreg_set_voltage_fail:
6394 i++;
6395vreg_get_fail:
6396 while (i)
6397 regulator_put(vregs_tdisc[--i]);
6398fail_gpio_oe:
6399 gpio_free(PMIC_GPIO_TDISC);
6400 return rc;
6401}
6402
6403static void tdisc_shinetsu_release(void)
6404{
6405 int i;
6406
6407 for (i = 0; i < ARRAY_SIZE(vregs_tdisc_name); i++)
6408 regulator_put(vregs_tdisc[i]);
6409
6410 gpio_free(PMIC_GPIO_TDISC);
6411 gpio_free(GPIO_JOYSTICK_EN);
6412}
6413
6414static int tdisc_shinetsu_enable(void)
6415{
6416 int i, rc = -EINVAL;
6417
6418 for (i = 0; i < ARRAY_SIZE(vregs_tdisc_name); i++) {
6419 rc = regulator_enable(vregs_tdisc[i]);
6420 if (rc < 0) {
6421 printk(KERN_ERR "%s: vreg %s enable failed (%d)\n",
6422 __func__, vregs_tdisc_name[i], rc);
6423 goto vreg_fail;
6424 }
6425 }
6426
6427 /* Enable the OE (output enable) gpio */
6428 gpio_set_value_cansleep(GPIO_JOYSTICK_EN, 1);
6429 /* voltage and gpio stabilization delay */
6430 msleep(50);
6431
6432 return 0;
6433vreg_fail:
6434 while (i)
6435 regulator_disable(vregs_tdisc[--i]);
6436 return rc;
6437}
6438
6439static int tdisc_shinetsu_disable(void)
6440{
6441 int i, rc;
6442
6443 for (i = 0; i < ARRAY_SIZE(vregs_tdisc_name); i++) {
6444 rc = regulator_disable(vregs_tdisc[i]);
6445 if (rc < 0) {
6446 printk(KERN_ERR "%s: vreg %s disable failed (%d)\n",
6447 __func__, vregs_tdisc_name[i], rc);
6448 goto tdisc_reg_fail;
6449 }
6450 }
6451
6452 /* Disable the OE (output enable) gpio */
6453 gpio_set_value_cansleep(GPIO_JOYSTICK_EN, 0);
6454
6455 return 0;
6456
6457tdisc_reg_fail:
6458 while (i)
6459 regulator_enable(vregs_tdisc[--i]);
6460 return rc;
6461}
6462
6463static struct tdisc_abs_values tdisc_abs = {
6464 .x_max = 32,
6465 .y_max = 32,
6466 .x_min = -32,
6467 .y_min = -32,
6468 .pressure_max = 32,
6469 .pressure_min = 0,
6470};
6471
6472static struct tdisc_platform_data tdisc_data = {
6473 .tdisc_setup = tdisc_shinetsu_setup,
6474 .tdisc_release = tdisc_shinetsu_release,
6475 .tdisc_enable = tdisc_shinetsu_enable,
6476 .tdisc_disable = tdisc_shinetsu_disable,
6477 .tdisc_wakeup = 0,
6478 .tdisc_gpio = PMIC_GPIO_TDISC,
6479 .tdisc_report_keys = true,
6480 .tdisc_report_relative = true,
6481 .tdisc_report_absolute = false,
6482 .tdisc_report_wheel = false,
6483 .tdisc_reverse_x = false,
6484 .tdisc_reverse_y = true,
6485 .tdisc_abs = &tdisc_abs,
6486};
6487
6488static struct i2c_board_info msm_i2c_gsbi3_tdisc_info[] = {
6489 {
6490 I2C_BOARD_INFO("vtd518", TDISC_I2C_SLAVE_ADDR),
6491 .irq = TDISC_INT,
6492 .platform_data = &tdisc_data,
6493 },
6494};
6495#endif
6496
6497#define PM_GPIO_CDC_RST_N 20
6498#define GPIO_CDC_RST_N PM8058_GPIO_PM_TO_SYS(PM_GPIO_CDC_RST_N)
6499
6500static struct regulator *vreg_timpani_1;
6501static struct regulator *vreg_timpani_2;
6502
6503static unsigned int msm_timpani_setup_power(void)
6504{
6505 int rc;
6506
6507 vreg_timpani_1 = regulator_get(NULL, "8058_l0");
6508 if (IS_ERR(vreg_timpani_1)) {
6509 pr_err("%s: Unable to get 8058_l0\n", __func__);
6510 return -ENODEV;
6511 }
6512
6513 vreg_timpani_2 = regulator_get(NULL, "8058_s3");
6514 if (IS_ERR(vreg_timpani_2)) {
6515 pr_err("%s: Unable to get 8058_s3\n", __func__);
6516 regulator_put(vreg_timpani_1);
6517 return -ENODEV;
6518 }
6519
6520 rc = regulator_set_voltage(vreg_timpani_1, 1200000, 1200000);
6521 if (rc) {
6522 pr_err("%s: unable to set L0 voltage to 1.2V\n", __func__);
6523 goto fail;
6524 }
6525
6526 rc = regulator_set_voltage(vreg_timpani_2, 1800000, 1800000);
6527 if (rc) {
6528 pr_err("%s: unable to set S3 voltage to 1.8V\n", __func__);
6529 goto fail;
6530 }
6531
6532 rc = regulator_enable(vreg_timpani_1);
6533 if (rc) {
6534 pr_err("%s: Enable regulator 8058_l0 failed\n", __func__);
6535 goto fail;
6536 }
6537
6538 /* The settings for LDO0 should be set such that
6539 * it doesn't require to reset the timpani. */
6540 rc = regulator_set_optimum_mode(vreg_timpani_1, 5000);
6541 if (rc < 0) {
6542 pr_err("Timpani regulator optimum mode setting failed\n");
6543 goto fail;
6544 }
6545
6546 rc = regulator_enable(vreg_timpani_2);
6547 if (rc) {
6548 pr_err("%s: Enable regulator 8058_s3 failed\n", __func__);
6549 regulator_disable(vreg_timpani_1);
6550 goto fail;
6551 }
6552
6553 rc = gpio_request(GPIO_CDC_RST_N, "CDC_RST_N");
6554 if (rc) {
6555 pr_err("%s: GPIO Request %d failed\n", __func__,
6556 GPIO_CDC_RST_N);
6557 regulator_disable(vreg_timpani_1);
6558 regulator_disable(vreg_timpani_2);
6559 goto fail;
6560 } else {
6561 gpio_direction_output(GPIO_CDC_RST_N, 1);
6562 usleep_range(1000, 1050);
6563 gpio_direction_output(GPIO_CDC_RST_N, 0);
6564 usleep_range(1000, 1050);
6565 gpio_direction_output(GPIO_CDC_RST_N, 1);
6566 gpio_free(GPIO_CDC_RST_N);
6567 }
6568 return rc;
6569
6570fail:
6571 regulator_put(vreg_timpani_1);
6572 regulator_put(vreg_timpani_2);
6573 return rc;
6574}
6575
6576static void msm_timpani_shutdown_power(void)
6577{
6578 int rc;
6579
6580 rc = regulator_disable(vreg_timpani_1);
6581 if (rc)
6582 pr_err("%s: Disable regulator 8058_l0 failed\n", __func__);
6583
6584 regulator_put(vreg_timpani_1);
6585
6586 rc = regulator_disable(vreg_timpani_2);
6587 if (rc)
6588 pr_err("%s: Disable regulator 8058_s3 failed\n", __func__);
6589
6590 regulator_put(vreg_timpani_2);
6591}
6592
6593/* Power analog function of codec */
6594static struct regulator *vreg_timpani_cdc_apwr;
6595static int msm_timpani_codec_power(int vreg_on)
6596{
6597 int rc = 0;
6598
6599 if (!vreg_timpani_cdc_apwr) {
6600
6601 vreg_timpani_cdc_apwr = regulator_get(NULL, "8058_s4");
6602
6603 if (IS_ERR(vreg_timpani_cdc_apwr)) {
6604 pr_err("%s: vreg_get failed (%ld)\n",
6605 __func__, PTR_ERR(vreg_timpani_cdc_apwr));
6606 rc = PTR_ERR(vreg_timpani_cdc_apwr);
6607 return rc;
6608 }
6609 }
6610
6611 if (vreg_on) {
6612
6613 rc = regulator_set_voltage(vreg_timpani_cdc_apwr,
6614 2200000, 2200000);
6615 if (rc) {
6616 pr_err("%s: unable to set 8058_s4 voltage to 2.2 V\n",
6617 __func__);
6618 goto vreg_fail;
6619 }
6620
6621 rc = regulator_enable(vreg_timpani_cdc_apwr);
6622 if (rc) {
6623 pr_err("%s: vreg_enable failed %d\n", __func__, rc);
6624 goto vreg_fail;
6625 }
6626 } else {
6627 rc = regulator_disable(vreg_timpani_cdc_apwr);
6628 if (rc) {
6629 pr_err("%s: vreg_disable failed %d\n",
6630 __func__, rc);
6631 goto vreg_fail;
6632 }
6633 }
6634
6635 return 0;
6636
6637vreg_fail:
6638 regulator_put(vreg_timpani_cdc_apwr);
6639 vreg_timpani_cdc_apwr = NULL;
6640 return rc;
6641}
6642
6643static struct marimba_codec_platform_data timpani_codec_pdata = {
6644 .marimba_codec_power = msm_timpani_codec_power,
6645};
6646
6647#define TIMPANI_SLAVE_ID_CDC_ADDR 0X77
6648#define TIMPANI_SLAVE_ID_QMEMBIST_ADDR 0X66
6649
6650static struct marimba_platform_data timpani_pdata = {
6651 .slave_id[MARIMBA_SLAVE_ID_CDC] = TIMPANI_SLAVE_ID_CDC_ADDR,
6652 .slave_id[MARIMBA_SLAVE_ID_QMEMBIST] = TIMPANI_SLAVE_ID_QMEMBIST_ADDR,
6653 .marimba_setup = msm_timpani_setup_power,
6654 .marimba_shutdown = msm_timpani_shutdown_power,
6655 .codec = &timpani_codec_pdata,
6656 .tsadc_ssbi_adap = MARIMBA_SSBI_ADAP,
6657};
6658
6659#define TIMPANI_I2C_SLAVE_ADDR 0xD
6660
6661static struct i2c_board_info msm_i2c_gsbi7_timpani_info[] = {
6662 {
6663 I2C_BOARD_INFO("timpani", TIMPANI_I2C_SLAVE_ADDR),
6664 .platform_data = &timpani_pdata,
6665 },
6666};
6667
6668#ifdef CONFIG_PMIC8901
6669
6670#define PM8901_GPIO_INT 91
6671
6672static struct pm8901_gpio_platform_data pm8901_mpp_data = {
6673 .gpio_base = PM8901_GPIO_PM_TO_SYS(0),
6674 .irq_base = PM8901_MPP_IRQ(PM8901_IRQ_BASE, 0),
6675};
6676
6677static struct resource pm8901_temp_alarm[] = {
6678 {
6679 .start = PM8901_TEMP_ALARM_IRQ(PM8901_IRQ_BASE),
6680 .end = PM8901_TEMP_ALARM_IRQ(PM8901_IRQ_BASE),
6681 .flags = IORESOURCE_IRQ,
6682 },
6683 {
6684 .start = PM8901_TEMP_HI_ALARM_IRQ(PM8901_IRQ_BASE),
6685 .end = PM8901_TEMP_HI_ALARM_IRQ(PM8901_IRQ_BASE),
6686 .flags = IORESOURCE_IRQ,
6687 },
6688};
6689
6690/*
6691 * Consumer specific regulator names:
6692 * regulator name consumer dev_name
6693 */
6694static struct regulator_consumer_supply vreg_consumers_8901_MPP0[] = {
6695 REGULATOR_SUPPLY("8901_mpp0", NULL),
6696};
6697static struct regulator_consumer_supply vreg_consumers_8901_USB_OTG[] = {
6698 REGULATOR_SUPPLY("8901_usb_otg", NULL),
6699};
6700static struct regulator_consumer_supply vreg_consumers_8901_HDMI_MVS[] = {
6701 REGULATOR_SUPPLY("8901_hdmi_mvs", NULL),
6702};
6703
6704#define PM8901_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
6705 _always_on, _active_high) \
6706 [PM8901_VREG_ID_##_id] = { \
6707 .init_data = { \
6708 .constraints = { \
6709 .valid_modes_mask = _modes, \
6710 .valid_ops_mask = _ops, \
6711 .min_uV = _min_uV, \
6712 .max_uV = _max_uV, \
6713 .input_uV = _min_uV, \
6714 .apply_uV = _apply_uV, \
6715 .always_on = _always_on, \
6716 }, \
6717 .consumer_supplies = vreg_consumers_8901_##_id, \
6718 .num_consumer_supplies = \
6719 ARRAY_SIZE(vreg_consumers_8901_##_id), \
6720 }, \
6721 .active_high = _active_high, \
6722 }
6723
6724#define PM8901_VREG_INIT_MPP(_id, _active_high) \
6725 PM8901_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL, \
6726 REGULATOR_CHANGE_STATUS, 0, 0, _active_high)
6727
6728#define PM8901_VREG_INIT_VS(_id) \
6729 PM8901_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL, \
6730 REGULATOR_CHANGE_STATUS, 0, 0, 0)
6731
6732static struct pm8901_vreg_pdata pm8901_vreg_init_pdata[PM8901_VREG_MAX] = {
6733 PM8901_VREG_INIT_MPP(MPP0, 1),
6734
6735 PM8901_VREG_INIT_VS(USB_OTG),
6736 PM8901_VREG_INIT_VS(HDMI_MVS),
6737};
6738
6739#define PM8901_VREG(_id) { \
6740 .name = "pm8901-regulator", \
6741 .id = _id, \
6742 .platform_data = &pm8901_vreg_init_pdata[_id], \
6743 .pdata_size = sizeof(pm8901_vreg_init_pdata[_id]), \
6744}
6745
6746static struct mfd_cell pm8901_subdevs[] = {
6747 { .name = "pm8901-mpp",
6748 .id = -1,
6749 .platform_data = &pm8901_mpp_data,
6750 .pdata_size = sizeof(pm8901_mpp_data),
6751 },
6752 { .name = "pm8901-tm",
6753 .id = -1,
6754 .num_resources = ARRAY_SIZE(pm8901_temp_alarm),
6755 .resources = pm8901_temp_alarm,
6756 },
6757 PM8901_VREG(PM8901_VREG_ID_MPP0),
6758 PM8901_VREG(PM8901_VREG_ID_USB_OTG),
6759 PM8901_VREG(PM8901_VREG_ID_HDMI_MVS),
6760};
6761
6762static struct pm8901_platform_data pm8901_platform_data = {
6763 .irq_base = PM8901_IRQ_BASE,
6764 .num_subdevs = ARRAY_SIZE(pm8901_subdevs),
6765 .sub_devices = pm8901_subdevs,
6766 .irq_trigger_flags = IRQF_TRIGGER_LOW,
6767};
6768
6769static struct i2c_board_info pm8901_boardinfo[] __initdata = {
6770 {
6771 I2C_BOARD_INFO("pm8901-core", 0x55),
6772 .irq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
6773 .platform_data = &pm8901_platform_data,
6774 },
6775};
6776
6777#endif /* CONFIG_PMIC8901 */
6778
6779#if defined(CONFIG_MARIMBA_CORE) && (defined(CONFIG_GPIO_SX150X) \
6780 || defined(CONFIG_GPIO_SX150X_MODULE))
6781
6782static struct regulator *vreg_bahama;
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006783static int msm_bahama_sys_rst = GPIO_MS_SYS_RESET_N;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006784
6785struct bahama_config_register{
6786 u8 reg;
6787 u8 value;
6788 u8 mask;
6789};
6790
6791enum version{
6792 VER_1_0,
6793 VER_2_0,
6794 VER_UNSUPPORTED = 0xFF
6795};
6796
6797static u8 read_bahama_ver(void)
6798{
6799 int rc;
6800 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA };
6801 u8 bahama_version;
6802
6803 rc = marimba_read_bit_mask(&config, 0x00, &bahama_version, 1, 0x1F);
6804 if (rc < 0) {
6805 printk(KERN_ERR
6806 "%s: version read failed: %d\n",
6807 __func__, rc);
6808 return VER_UNSUPPORTED;
6809 } else {
6810 printk(KERN_INFO
6811 "%s: version read got: 0x%x\n",
6812 __func__, bahama_version);
6813 }
6814
6815 switch (bahama_version) {
6816 case 0x08: /* varient of bahama v1 */
6817 case 0x10:
6818 case 0x00:
6819 return VER_1_0;
6820 case 0x09: /* variant of bahama v2 */
6821 return VER_2_0;
6822 default:
6823 return VER_UNSUPPORTED;
6824 }
6825}
6826
6827static unsigned int msm_bahama_setup_power(void)
6828{
6829 int rc = 0;
6830 const char *msm_bahama_regulator = "8058_s3";
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006831
6832 if (machine_is_msm8x60_dragon())
6833 msm_bahama_sys_rst = GPIO_CDC_RST_N;
6834
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006835 vreg_bahama = regulator_get(NULL, msm_bahama_regulator);
6836
6837 if (IS_ERR(vreg_bahama)) {
6838 rc = PTR_ERR(vreg_bahama);
6839 pr_err("%s: regulator_get %s = %d\n", __func__,
6840 msm_bahama_regulator, rc);
6841 }
6842
6843 if (!rc)
6844 rc = regulator_set_voltage(vreg_bahama, 1800000, 1800000);
6845 else {
6846 pr_err("%s: regulator_set_voltage %s = %d\n", __func__,
6847 msm_bahama_regulator, rc);
6848 goto unget;
6849 }
6850
6851 if (!rc)
6852 rc = regulator_enable(vreg_bahama);
6853 else {
6854 pr_err("%s: regulator_enable %s = %d\n", __func__,
6855 msm_bahama_regulator, rc);
6856 goto unget;
6857 }
6858
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006859 if (!rc) {
6860 rc = gpio_request(msm_bahama_sys_rst, "bahama sys_rst_n");
6861 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006862 pr_err("%s: gpio_request %d = %d\n", __func__,
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006863 msm_bahama_sys_rst, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006864 goto unenable;
6865 }
6866
Siddartha Mohanadoss72d796e2011-07-20 22:08:34 -07006867 if (!rc) {
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006868 gpio_direction_output(msm_bahama_sys_rst, 0);
Siddartha Mohanadoss72d796e2011-07-20 22:08:34 -07006869 usleep_range(1000, 1050);
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006870 gpio_set_value_cansleep(msm_bahama_sys_rst, 1);
Siddartha Mohanadoss72d796e2011-07-20 22:08:34 -07006871 usleep_range(1000, 1050);
6872 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006873 pr_err("%s: gpio_direction_output %d = %d\n", __func__,
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006874 msm_bahama_sys_rst, rc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006875 goto unrequest;
6876 }
6877
6878 return rc;
6879
6880unrequest:
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006881 gpio_free(msm_bahama_sys_rst);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006882unenable:
6883 regulator_disable(vreg_bahama);
6884unget:
6885 regulator_put(vreg_bahama);
6886 return rc;
6887};
6888static unsigned int msm_bahama_shutdown_power(int value)
6889
6890
6891{
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006892 gpio_set_value_cansleep(msm_bahama_sys_rst, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006893
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04006894 gpio_free(msm_bahama_sys_rst);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07006895
6896 regulator_disable(vreg_bahama);
6897
6898 regulator_put(vreg_bahama);
6899
6900 return 0;
6901};
6902
6903static unsigned int msm_bahama_core_config(int type)
6904{
6905 int rc = 0;
6906
6907 if (type == BAHAMA_ID) {
6908
6909 int i;
6910 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA };
6911
6912 const struct bahama_config_register v20_init[] = {
6913 /* reg, value, mask */
6914 { 0xF4, 0x84, 0xFF }, /* AREG */
6915 { 0xF0, 0x04, 0xFF } /* DREG */
6916 };
6917
6918 if (read_bahama_ver() == VER_2_0) {
6919 for (i = 0; i < ARRAY_SIZE(v20_init); i++) {
6920 u8 value = v20_init[i].value;
6921 rc = marimba_write_bit_mask(&config,
6922 v20_init[i].reg,
6923 &value,
6924 sizeof(v20_init[i].value),
6925 v20_init[i].mask);
6926 if (rc < 0) {
6927 printk(KERN_ERR
6928 "%s: reg %d write failed: %d\n",
6929 __func__, v20_init[i].reg, rc);
6930 return rc;
6931 }
6932 printk(KERN_INFO "%s: reg 0x%02x value 0x%02x"
6933 " mask 0x%02x\n",
6934 __func__, v20_init[i].reg,
6935 v20_init[i].value, v20_init[i].mask);
6936 }
6937 }
6938 }
6939 printk(KERN_INFO "core type: %d\n", type);
6940
6941 return rc;
6942}
6943
6944static struct regulator *fm_regulator_s3;
6945static struct msm_xo_voter *fm_clock;
6946
6947static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
6948{
6949 int rc = 0;
6950 struct pm8058_gpio cfg = {
6951 .direction = PM_GPIO_DIR_IN,
6952 .pull = PM_GPIO_PULL_NO,
6953 .vin_sel = PM_GPIO_VIN_S3,
6954 .function = PM_GPIO_FUNC_NORMAL,
6955 .inv_int_pol = 0,
6956 };
6957
6958 if (!fm_regulator_s3) {
6959 fm_regulator_s3 = regulator_get(NULL, "8058_s3");
6960 if (IS_ERR(fm_regulator_s3)) {
6961 rc = PTR_ERR(fm_regulator_s3);
6962 printk(KERN_ERR "%s: regulator get s3 (%d)\n",
6963 __func__, rc);
6964 goto out;
6965 }
6966 }
6967
6968
6969 rc = regulator_set_voltage(fm_regulator_s3, 1800000, 1800000);
6970 if (rc < 0) {
6971 printk(KERN_ERR "%s: regulator set voltage failed (%d)\n",
6972 __func__, rc);
6973 goto fm_fail_put;
6974 }
6975
6976 rc = regulator_enable(fm_regulator_s3);
6977 if (rc < 0) {
6978 printk(KERN_ERR "%s: regulator s3 enable failed (%d)\n",
6979 __func__, rc);
6980 goto fm_fail_put;
6981 }
6982
6983 /*Vote for XO clock*/
6984 fm_clock = msm_xo_get(MSM_XO_TCXO_D0, "fm_power");
6985
6986 if (IS_ERR(fm_clock)) {
6987 rc = PTR_ERR(fm_clock);
6988 printk(KERN_ERR "%s: Couldn't get TCXO_D0 vote for FM (%d)\n",
6989 __func__, rc);
6990 goto fm_fail_switch;
6991 }
6992
6993 rc = msm_xo_mode_vote(fm_clock, MSM_XO_MODE_ON);
6994 if (rc < 0) {
6995 printk(KERN_ERR "%s: Failed to vote for TCX0_D0 ON (%d)\n",
6996 __func__, rc);
6997 goto fm_fail_vote;
6998 }
6999
7000 /*GPIO 18 on PMIC is FM_IRQ*/
7001 rc = pm8058_gpio_config(FM_GPIO, &cfg);
7002 if (rc) {
7003 printk(KERN_ERR "%s: return val of pm8058_gpio_config: %d\n",
7004 __func__, rc);
7005 goto fm_fail_clock;
7006 }
7007 goto out;
7008
7009fm_fail_clock:
7010 msm_xo_mode_vote(fm_clock, MSM_XO_MODE_OFF);
7011fm_fail_vote:
7012 msm_xo_put(fm_clock);
7013fm_fail_switch:
7014 regulator_disable(fm_regulator_s3);
7015fm_fail_put:
7016 regulator_put(fm_regulator_s3);
7017out:
7018 return rc;
7019};
7020
7021static void fm_radio_shutdown(struct marimba_fm_platform_data *pdata)
7022{
7023 int rc = 0;
7024 if (fm_regulator_s3 != NULL) {
7025 rc = regulator_disable(fm_regulator_s3);
7026 if (rc < 0) {
7027 printk(KERN_ERR "%s: regulator s3 disable (%d)\n",
7028 __func__, rc);
7029 }
7030 regulator_put(fm_regulator_s3);
7031 fm_regulator_s3 = NULL;
7032 }
7033 printk(KERN_ERR "%s: Voting off for XO", __func__);
7034
7035 if (fm_clock != NULL) {
7036 rc = msm_xo_mode_vote(fm_clock, MSM_XO_MODE_OFF);
7037 if (rc < 0) {
7038 printk(KERN_ERR "%s: Voting off XO clock (%d)\n",
7039 __func__, rc);
7040 }
7041 msm_xo_put(fm_clock);
7042 }
7043 printk(KERN_ERR "%s: coming out of fm_radio_shutdown", __func__);
7044}
7045
7046/* Slave id address for FM/CDC/QMEMBIST
7047 * Values can be programmed using Marimba slave id 0
7048 * should there be a conflict with other I2C devices
7049 * */
7050#define BAHAMA_SLAVE_ID_FM_ADDR 0x2A
7051#define BAHAMA_SLAVE_ID_QMEMBIST_ADDR 0x7B
7052
7053static struct marimba_fm_platform_data marimba_fm_pdata = {
7054 .fm_setup = fm_radio_setup,
7055 .fm_shutdown = fm_radio_shutdown,
7056 .irq = PM8058_GPIO_IRQ(PM8058_IRQ_BASE, FM_GPIO),
7057 .is_fm_soc_i2s_master = false,
7058 .config_i2s_gpio = NULL,
7059};
7060
7061/*
7062Just initializing the BAHAMA related slave
7063*/
7064static struct marimba_platform_data marimba_pdata = {
7065 .slave_id[SLAVE_ID_BAHAMA_FM] = BAHAMA_SLAVE_ID_FM_ADDR,
7066 .slave_id[SLAVE_ID_BAHAMA_QMEMBIST] = BAHAMA_SLAVE_ID_QMEMBIST_ADDR,
7067 .bahama_setup = msm_bahama_setup_power,
7068 .bahama_shutdown = msm_bahama_shutdown_power,
7069 .bahama_core_config = msm_bahama_core_config,
7070 .fm = &marimba_fm_pdata,
7071 .tsadc_ssbi_adap = MARIMBA_SSBI_ADAP,
7072};
7073
7074
7075static struct i2c_board_info msm_marimba_board_info[] = {
7076 {
7077 I2C_BOARD_INFO("marimba", 0xc),
7078 .platform_data = &marimba_pdata,
7079 }
7080};
7081#endif /* CONFIG_MAIMBA_CORE */
7082
7083#ifdef CONFIG_I2C
7084#define I2C_SURF 1
7085#define I2C_FFA (1 << 1)
7086#define I2C_RUMI (1 << 2)
7087#define I2C_SIM (1 << 3)
7088#define I2C_FLUID (1 << 4)
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007089#define I2C_DRAGON (1 << 5)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007090
7091struct i2c_registry {
7092 u8 machs;
7093 int bus;
7094 struct i2c_board_info *info;
7095 int len;
7096};
7097
7098static struct i2c_registry msm8x60_i2c_devices[] __initdata = {
7099#ifdef CONFIG_PMIC8058
7100 {
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007101 I2C_SURF | I2C_FFA | I2C_FLUID | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007102 MSM_SSBI1_I2C_BUS_ID,
7103 pm8058_boardinfo,
7104 ARRAY_SIZE(pm8058_boardinfo),
7105 },
7106#endif
7107#ifdef CONFIG_PMIC8901
7108 {
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007109 I2C_SURF | I2C_FFA | I2C_FLUID | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007110 MSM_SSBI2_I2C_BUS_ID,
7111 pm8901_boardinfo,
7112 ARRAY_SIZE(pm8901_boardinfo),
7113 },
7114#endif
7115#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
7116 {
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007117 I2C_SURF | I2C_FFA | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007118 MSM_GSBI8_QUP_I2C_BUS_ID,
7119 core_expander_i2c_info,
7120 ARRAY_SIZE(core_expander_i2c_info),
7121 },
7122 {
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007123 I2C_SURF | I2C_FFA | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007124 MSM_GSBI8_QUP_I2C_BUS_ID,
7125 docking_expander_i2c_info,
7126 ARRAY_SIZE(docking_expander_i2c_info),
7127 },
7128 {
7129 I2C_SURF,
7130 MSM_GSBI8_QUP_I2C_BUS_ID,
7131 surf_expanders_i2c_info,
7132 ARRAY_SIZE(surf_expanders_i2c_info),
7133 },
7134 {
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007135 I2C_SURF | I2C_FFA | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007136 MSM_GSBI3_QUP_I2C_BUS_ID,
7137 fha_expanders_i2c_info,
7138 ARRAY_SIZE(fha_expanders_i2c_info),
7139 },
7140 {
7141 I2C_FLUID,
7142 MSM_GSBI3_QUP_I2C_BUS_ID,
7143 fluid_expanders_i2c_info,
7144 ARRAY_SIZE(fluid_expanders_i2c_info),
7145 },
7146 {
7147 I2C_FLUID,
7148 MSM_GSBI8_QUP_I2C_BUS_ID,
7149 fluid_core_expander_i2c_info,
7150 ARRAY_SIZE(fluid_core_expander_i2c_info),
7151 },
7152#endif
7153#if defined(CONFIG_TOUCHDISC_VTD518_SHINETSU) || \
7154 defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
7155 {
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007156 I2C_SURF | I2C_FFA | I2C_FLUID | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007157 MSM_GSBI3_QUP_I2C_BUS_ID,
7158 msm_i2c_gsbi3_tdisc_info,
7159 ARRAY_SIZE(msm_i2c_gsbi3_tdisc_info),
7160 },
7161#endif
7162 {
Zhang Chang Ken211df572011-07-05 19:16:39 -04007163 I2C_SURF | I2C_FFA | I2C_FLUID,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007164 MSM_GSBI3_QUP_I2C_BUS_ID,
7165 cy8ctmg200_board_info,
7166 ARRAY_SIZE(cy8ctmg200_board_info),
7167 },
Zhang Chang Ken211df572011-07-05 19:16:39 -04007168 {
7169 I2C_DRAGON,
7170 MSM_GSBI3_QUP_I2C_BUS_ID,
7171 cy8ctma340_dragon_board_info,
7172 ARRAY_SIZE(cy8ctma340_dragon_board_info),
7173 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007174#if defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C) || \
7175 defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C_MODULE)
7176 {
7177 I2C_FLUID,
7178 MSM_GSBI3_QUP_I2C_BUS_ID,
7179 cyttsp_fluid_info,
7180 ARRAY_SIZE(cyttsp_fluid_info),
7181 },
7182 {
7183 I2C_FFA | I2C_SURF,
7184 MSM_GSBI3_QUP_I2C_BUS_ID,
7185 cyttsp_ffa_info,
7186 ARRAY_SIZE(cyttsp_ffa_info),
7187 },
7188#endif
7189#ifdef CONFIG_MSM_CAMERA
Jilai Wang971f97f2011-07-13 14:25:25 -04007190 {
7191 I2C_SURF | I2C_FFA | I2C_FLUID ,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007192 MSM_GSBI4_QUP_I2C_BUS_ID,
7193 msm_camera_boardinfo,
7194 ARRAY_SIZE(msm_camera_boardinfo),
7195 },
Jilai Wang971f97f2011-07-13 14:25:25 -04007196 {
7197 I2C_DRAGON,
7198 MSM_GSBI4_QUP_I2C_BUS_ID,
7199 msm_camera_dragon_boardinfo,
7200 ARRAY_SIZE(msm_camera_dragon_boardinfo),
7201 },
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007202#endif
7203 {
7204 I2C_SURF | I2C_FFA | I2C_FLUID,
7205 MSM_GSBI7_QUP_I2C_BUS_ID,
7206 msm_i2c_gsbi7_timpani_info,
7207 ARRAY_SIZE(msm_i2c_gsbi7_timpani_info),
7208 },
7209#if defined(CONFIG_MARIMBA_CORE)
7210 {
Zhang Chang Kene1fd3da2011-08-10 08:25:57 -04007211 I2C_SURF | I2C_FFA | I2C_FLUID | I2C_DRAGON,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007212 MSM_GSBI7_QUP_I2C_BUS_ID,
7213 msm_marimba_board_info,
7214 ARRAY_SIZE(msm_marimba_board_info),
7215 },
7216#endif /* CONFIG_MARIMBA_CORE */
7217#ifdef CONFIG_ISL9519_CHARGER
7218 {
7219 I2C_SURF | I2C_FFA,
7220 MSM_GSBI8_QUP_I2C_BUS_ID,
7221 isl_charger_i2c_info,
7222 ARRAY_SIZE(isl_charger_i2c_info),
7223 },
7224#endif
7225#if defined(CONFIG_HAPTIC_ISA1200) || \
7226 defined(CONFIG_HAPTIC_ISA1200_MODULE)
7227 {
7228 I2C_FLUID,
7229 MSM_GSBI8_QUP_I2C_BUS_ID,
7230 msm_isa1200_board_info,
7231 ARRAY_SIZE(msm_isa1200_board_info),
7232 },
7233#endif
7234#if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
7235 {
7236 I2C_FLUID,
7237 MSM_GSBI8_QUP_I2C_BUS_ID,
7238 smb137b_charger_i2c_info,
7239 ARRAY_SIZE(smb137b_charger_i2c_info),
7240 },
7241#endif
7242#if defined(CONFIG_BATTERY_BQ27520) || \
7243 defined(CONFIG_BATTERY_BQ27520_MODULE)
7244 {
7245 I2C_FLUID,
7246 MSM_GSBI8_QUP_I2C_BUS_ID,
7247 msm_bq27520_board_info,
7248 ARRAY_SIZE(msm_bq27520_board_info),
7249 },
7250#endif
7251};
7252#endif /* CONFIG_I2C */
7253
7254static void fixup_i2c_configs(void)
7255{
7256#ifdef CONFIG_I2C
7257#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
7258 if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion())
7259 sx150x_data[SX150X_CORE].irq_summary =
7260 PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT2_N);
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007261 else if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa() ||
7262 machine_is_msm8x60_dragon())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007263 sx150x_data[SX150X_CORE].irq_summary =
7264 PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT1_N);
7265 else if (machine_is_msm8x60_fluid())
7266 sx150x_data[SX150X_CORE_FLUID].irq_summary =
7267 PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT1_N);
7268#endif
7269 /*
7270 * Set PMIC 8901 MPP0 active_high to 0 for surf and charm_surf. This
7271 * implies that the regulator connected to MPP0 is enabled when
7272 * MPP0 is low.
7273 */
7274 if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion())
7275 pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 0;
7276 else
7277 pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 1;
7278#endif
7279}
7280
7281static void register_i2c_devices(void)
7282{
7283#ifdef CONFIG_I2C
7284 u8 mach_mask = 0;
7285 int i;
7286
7287 /* Build the matching 'supported_machs' bitmask */
7288 if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion())
7289 mach_mask = I2C_SURF;
7290 else if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa())
7291 mach_mask = I2C_FFA;
7292 else if (machine_is_msm8x60_rumi3())
7293 mach_mask = I2C_RUMI;
7294 else if (machine_is_msm8x60_sim())
7295 mach_mask = I2C_SIM;
7296 else if (machine_is_msm8x60_fluid())
7297 mach_mask = I2C_FLUID;
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007298 else if (machine_is_msm8x60_dragon())
7299 mach_mask = I2C_DRAGON;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007300 else
7301 pr_err("unmatched machine ID in register_i2c_devices\n");
7302
7303 /* Run the array and install devices as appropriate */
7304 for (i = 0; i < ARRAY_SIZE(msm8x60_i2c_devices); ++i) {
7305 if (msm8x60_i2c_devices[i].machs & mach_mask)
7306 i2c_register_board_info(msm8x60_i2c_devices[i].bus,
7307 msm8x60_i2c_devices[i].info,
7308 msm8x60_i2c_devices[i].len);
7309 }
7310#endif
7311}
7312
7313static void __init msm8x60_init_uart12dm(void)
7314{
7315#if !defined(CONFIG_USB_PEHCI_HCD) && !defined(CONFIG_USB_PEHCI_HCD_MODULE)
7316 /* 0x1D000000 now belongs to EBI2:CS3 i.e. USB ISP Controller */
7317 void *fpga_mem = ioremap_nocache(0x1D000000, SZ_4K);
7318
7319 if (!fpga_mem)
7320 pr_err("%s(): Error getting memory\n", __func__);
7321
7322 /* Advanced mode */
7323 writew(0xFFFF, fpga_mem + 0x15C);
7324 /* FPGA_UART_SEL */
7325 writew(0, fpga_mem + 0x172);
7326 /* FPGA_GPIO_CONFIG_117 */
7327 writew(1, fpga_mem + 0xEA);
7328 /* FPGA_GPIO_CONFIG_118 */
7329 writew(1, fpga_mem + 0xEC);
7330 mb();
7331 iounmap(fpga_mem);
7332#endif
7333}
7334
7335#define MSM_GSBI9_PHYS 0x19900000
7336#define GSBI_DUAL_MODE_CODE 0x60
7337
7338static void __init msm8x60_init_buses(void)
7339{
7340#ifdef CONFIG_I2C_QUP
7341 void *gsbi_mem = ioremap_nocache(0x19C00000, 4);
7342 /* Setting protocol code to 0x60 for dual UART/I2C in GSBI12 */
7343 writel_relaxed(0x6 << 4, gsbi_mem);
7344 /* Ensure protocol code is written before proceeding further */
7345 mb();
7346 iounmap(gsbi_mem);
7347
7348 msm_gsbi3_qup_i2c_device.dev.platform_data = &msm_gsbi3_qup_i2c_pdata;
7349 msm_gsbi4_qup_i2c_device.dev.platform_data = &msm_gsbi4_qup_i2c_pdata;
7350 msm_gsbi7_qup_i2c_device.dev.platform_data = &msm_gsbi7_qup_i2c_pdata;
7351 msm_gsbi8_qup_i2c_device.dev.platform_data = &msm_gsbi8_qup_i2c_pdata;
7352
7353#ifdef CONFIG_MSM_GSBI9_UART
7354 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
7355 /* Setting protocol code to 0x60 for dual UART/I2C in GSBI9 */
7356 gsbi_mem = ioremap_nocache(MSM_GSBI9_PHYS, 4);
7357 writel_relaxed(GSBI_DUAL_MODE_CODE, gsbi_mem);
7358 iounmap(gsbi_mem);
7359 msm_gsbi9_qup_i2c_pdata.use_gsbi_shared_mode = 1;
7360 }
7361#endif
7362 msm_gsbi9_qup_i2c_device.dev.platform_data = &msm_gsbi9_qup_i2c_pdata;
7363 msm_gsbi12_qup_i2c_device.dev.platform_data = &msm_gsbi12_qup_i2c_pdata;
7364#endif
7365#if defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
7366 msm_gsbi1_qup_spi_device.dev.platform_data = &msm_gsbi1_qup_spi_pdata;
7367#endif
7368#ifdef CONFIG_I2C_SSBI
7369 msm_device_ssbi1.dev.platform_data = &msm_ssbi1_pdata;
7370 msm_device_ssbi2.dev.platform_data = &msm_ssbi2_pdata;
7371 msm_device_ssbi3.dev.platform_data = &msm_ssbi3_pdata;
7372#endif
7373
7374 if (machine_is_msm8x60_fluid()) {
7375#if (defined(CONFIG_USB_EHCI_MSM_72K) && \
7376 (defined(CONFIG_SMB137B_CHARGER) || \
7377 defined(CONFIG_SMB137B_CHARGER_MODULE)))
7378 msm_otg_pdata.vbus_power = msm_hsusb_smb137b_vbus_power;
7379#endif
7380#if defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
7381 msm_gsbi10_qup_spi_device.dev.platform_data =
7382 &msm_gsbi10_qup_spi_pdata;
7383#endif
7384 }
7385
7386#if defined(CONFIG_USB_GADGET_MSM_72K) || defined(CONFIG_USB_EHCI_HCD)
7387 /*
7388 * We can not put USB regulators (8058_l6 and 8058_l7) in LPM
7389 * when we depend on USB PHY for VBUS/ID notifications. VBUS
7390 * and ID notifications are available only on V2 surf and FFA
7391 * with a hardware workaround.
7392 */
7393 if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2 &&
7394 (machine_is_msm8x60_surf() ||
7395 (machine_is_msm8x60_ffa() &&
7396 pmic_id_notif_supported)))
7397 msm_otg_pdata.phy_can_powercollapse = 1;
7398 msm_device_otg.dev.platform_data = &msm_otg_pdata;
7399#endif
7400
7401#ifdef CONFIG_USB_GADGET_MSM_72K
7402 msm_device_gadget_peripheral.dev.platform_data = &msm_gadget_pdata;
7403#endif
7404
7405#ifdef CONFIG_SERIAL_MSM_HS
7406 msm_uart_dm1_pdata.wakeup_irq = gpio_to_irq(54); /* GSBI6(2) */
7407 msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
7408#endif
7409#ifdef CONFIG_MSM_GSBI9_UART
7410 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
7411 msm_device_uart_gsbi9 = msm_add_gsbi9_uart();
7412 if (IS_ERR(msm_device_uart_gsbi9))
7413 pr_err("%s(): Failed to create uart gsbi9 device\n",
7414 __func__);
7415 }
7416#endif
7417
7418#ifdef CONFIG_MSM_BUS_SCALING
7419
7420 /* RPM calls are only enabled on V2 */
7421 if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 2) {
7422 msm_bus_apps_fabric_pdata.rpm_enabled = 1;
7423 msm_bus_sys_fabric_pdata.rpm_enabled = 1;
7424 msm_bus_mm_fabric_pdata.rpm_enabled = 1;
7425 msm_bus_sys_fpb_pdata.rpm_enabled = 1;
7426 msm_bus_cpss_fpb_pdata.rpm_enabled = 1;
7427 }
7428
7429 msm_bus_apps_fabric.dev.platform_data = &msm_bus_apps_fabric_pdata;
7430 msm_bus_sys_fabric.dev.platform_data = &msm_bus_sys_fabric_pdata;
7431 msm_bus_mm_fabric.dev.platform_data = &msm_bus_mm_fabric_pdata;
7432 msm_bus_sys_fpb.dev.platform_data = &msm_bus_sys_fpb_pdata;
7433 msm_bus_cpss_fpb.dev.platform_data = &msm_bus_cpss_fpb_pdata;
7434#endif
7435}
7436
7437static void __init msm8x60_map_io(void)
7438{
7439 msm_shared_ram_phys = MSM_SHARED_RAM_PHYS;
7440 msm_map_msm8x60_io();
7441}
7442
7443/*
7444 * Most segments of the EBI2 bus are disabled by default.
7445 */
7446static void __init msm8x60_init_ebi2(void)
7447{
7448 uint32_t ebi2_cfg;
7449 void *ebi2_cfg_ptr;
7450
7451 ebi2_cfg_ptr = ioremap_nocache(0x1a100000, sizeof(uint32_t));
7452 if (ebi2_cfg_ptr != 0) {
7453 ebi2_cfg = readl_relaxed(ebi2_cfg_ptr);
7454
7455 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007456 machine_is_msm8x60_fluid() ||
7457 machine_is_msm8x60_dragon())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007458 ebi2_cfg |= (1 << 4) | (1 << 5); /* CS2, CS3 */
7459 else if (machine_is_msm8x60_sim())
7460 ebi2_cfg |= (1 << 4); /* CS2 */
7461 else if (machine_is_msm8x60_rumi3())
7462 ebi2_cfg |= (1 << 5); /* CS3 */
7463
7464 writel_relaxed(ebi2_cfg, ebi2_cfg_ptr);
7465 iounmap(ebi2_cfg_ptr);
7466 }
7467
7468 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
Zhang Chang Ken6baadf02011-08-05 09:48:15 -04007469 machine_is_msm8x60_fluid() || machine_is_msm8x60_dragon()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007470 ebi2_cfg_ptr = ioremap_nocache(0x1a110000, SZ_4K);
7471 if (ebi2_cfg_ptr != 0) {
7472 /* EBI2_XMEM_CFG:PWRSAVE_MODE off */
7473 writel_relaxed(0UL, ebi2_cfg_ptr);
7474
7475 /* CS2: Delay 9 cycles (140ns@64MHz) between SMSC
7476 * LAN9221 Ethernet controller reads and writes.
7477 * The lowest 4 bits are the read delay, the next
7478 * 4 are the write delay. */
7479 writel_relaxed(0x031F1C99, ebi2_cfg_ptr + 0x10);
7480#if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
7481 /*
7482 * RECOVERY=5, HOLD_WR=1
7483 * INIT_LATENCY_WR=1, INIT_LATENCY_RD=1
7484 * WAIT_WR=1, WAIT_RD=2
7485 */
7486 writel_relaxed(0x51010112, ebi2_cfg_ptr + 0x14);
7487 /*
7488 * HOLD_RD=1
7489 * ADV_OE_RECOVERY=0, ADDR_HOLD_ENA=1
7490 */
7491 writel_relaxed(0x01000020, ebi2_cfg_ptr + 0x34);
7492#else
7493 /* EBI2 CS3 muxed address/data,
7494 * two cyc addr enable */
7495 writel_relaxed(0xA3030020, ebi2_cfg_ptr + 0x34);
7496
7497#endif
7498 iounmap(ebi2_cfg_ptr);
7499 }
7500 }
7501}
7502
7503static void __init msm8x60_configure_smc91x(void)
7504{
7505 if (machine_is_msm8x60_sim()) {
7506
7507 smc91x_resources[0].start = 0x1b800300;
7508 smc91x_resources[0].end = 0x1b8003ff;
7509
7510 smc91x_resources[1].start = (NR_MSM_IRQS + 40);
7511 smc91x_resources[1].end = (NR_MSM_IRQS + 40);
7512
7513 } else if (machine_is_msm8x60_rumi3()) {
7514
7515 smc91x_resources[0].start = 0x1d000300;
7516 smc91x_resources[0].end = 0x1d0003ff;
7517
7518 smc91x_resources[1].start = TLMM_MSM_DIR_CONN_IRQ_0;
7519 smc91x_resources[1].end = TLMM_MSM_DIR_CONN_IRQ_0;
7520 }
7521}
7522
7523static void __init msm8x60_init_tlmm(void)
7524{
7525 if (machine_is_msm8x60_rumi3())
7526 msm_gpio_install_direct_irq(0, 0, 1);
7527}
7528
7529#if (defined(CONFIG_MMC_MSM_SDC1_SUPPORT)\
7530 || defined(CONFIG_MMC_MSM_SDC2_SUPPORT)\
7531 || defined(CONFIG_MMC_MSM_SDC3_SUPPORT)\
7532 || defined(CONFIG_MMC_MSM_SDC4_SUPPORT)\
7533 || defined(CONFIG_MMC_MSM_SDC5_SUPPORT))
7534
7535/* 8x60 is having 5 SDCC controllers */
7536#define MAX_SDCC_CONTROLLER 5
7537
7538struct msm_sdcc_gpio {
7539 /* maximum 10 GPIOs per SDCC controller */
7540 s16 no;
7541 /* name of this GPIO */
7542 const char *name;
7543 bool always_on;
7544 bool is_enabled;
7545};
7546
7547#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
7548static struct msm_sdcc_gpio sdc1_gpio_cfg[] = {
7549 {159, "sdc1_dat_0"},
7550 {160, "sdc1_dat_1"},
7551 {161, "sdc1_dat_2"},
7552 {162, "sdc1_dat_3"},
7553#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
7554 {163, "sdc1_dat_4"},
7555 {164, "sdc1_dat_5"},
7556 {165, "sdc1_dat_6"},
7557 {166, "sdc1_dat_7"},
7558#endif
7559 {167, "sdc1_clk"},
7560 {168, "sdc1_cmd"}
7561};
7562#endif
7563
7564#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
7565static struct msm_sdcc_gpio sdc2_gpio_cfg[] = {
7566 {143, "sdc2_dat_0"},
7567 {144, "sdc2_dat_1", 1},
7568 {145, "sdc2_dat_2"},
7569 {146, "sdc2_dat_3"},
7570#ifdef CONFIG_MMC_MSM_SDC2_8_BIT_SUPPORT
7571 {147, "sdc2_dat_4"},
7572 {148, "sdc2_dat_5"},
7573 {149, "sdc2_dat_6"},
7574 {150, "sdc2_dat_7"},
7575#endif
7576 {151, "sdc2_cmd"},
7577 {152, "sdc2_clk", 1}
7578};
7579#endif
7580
7581#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
7582static struct msm_sdcc_gpio sdc5_gpio_cfg[] = {
7583 {95, "sdc5_cmd"},
7584 {96, "sdc5_dat_3"},
7585 {97, "sdc5_clk", 1},
7586 {98, "sdc5_dat_2"},
7587 {99, "sdc5_dat_1", 1},
7588 {100, "sdc5_dat_0"}
7589};
7590#endif
7591
7592struct msm_sdcc_pad_pull_cfg {
7593 enum msm_tlmm_pull_tgt pull;
7594 u32 pull_val;
7595};
7596
7597struct msm_sdcc_pad_drv_cfg {
7598 enum msm_tlmm_hdrive_tgt drv;
7599 u32 drv_val;
7600};
7601
7602#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
7603static struct msm_sdcc_pad_drv_cfg sdc3_pad_on_drv_cfg[] = {
7604 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_8MA},
7605 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_8MA},
7606 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_8MA}
7607};
7608
7609static struct msm_sdcc_pad_pull_cfg sdc3_pad_on_pull_cfg[] = {
7610 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
7611 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
7612};
7613
7614static struct msm_sdcc_pad_drv_cfg sdc3_pad_off_drv_cfg[] = {
7615 {TLMM_HDRV_SDC3_CLK, GPIO_CFG_2MA},
7616 {TLMM_HDRV_SDC3_CMD, GPIO_CFG_2MA},
7617 {TLMM_HDRV_SDC3_DATA, GPIO_CFG_2MA}
7618};
7619
7620static struct msm_sdcc_pad_pull_cfg sdc3_pad_off_pull_cfg[] = {
7621 {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_DOWN},
7622 {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_DOWN}
7623};
7624#endif
7625
7626#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
7627static struct msm_sdcc_pad_drv_cfg sdc4_pad_on_drv_cfg[] = {
7628 {TLMM_HDRV_SDC4_CLK, GPIO_CFG_8MA},
7629 {TLMM_HDRV_SDC4_CMD, GPIO_CFG_8MA},
7630 {TLMM_HDRV_SDC4_DATA, GPIO_CFG_8MA}
7631};
7632
7633static struct msm_sdcc_pad_pull_cfg sdc4_pad_on_pull_cfg[] = {
7634 {TLMM_PULL_SDC4_CMD, GPIO_CFG_PULL_UP},
7635 {TLMM_PULL_SDC4_DATA, GPIO_CFG_PULL_UP}
7636};
7637
7638static struct msm_sdcc_pad_drv_cfg sdc4_pad_off_drv_cfg[] = {
7639 {TLMM_HDRV_SDC4_CLK, GPIO_CFG_2MA},
7640 {TLMM_HDRV_SDC4_CMD, GPIO_CFG_2MA},
7641 {TLMM_HDRV_SDC4_DATA, GPIO_CFG_2MA}
7642};
7643
7644static struct msm_sdcc_pad_pull_cfg sdc4_pad_off_pull_cfg[] = {
7645 {TLMM_PULL_SDC4_CMD, GPIO_CFG_PULL_DOWN},
7646 {TLMM_PULL_SDC4_DATA, GPIO_CFG_PULL_DOWN}
7647};
7648#endif
7649
7650struct msm_sdcc_pin_cfg {
7651 /*
7652 * = 1 if controller pins are using gpios
7653 * = 0 if controller has dedicated MSM pins
7654 */
7655 u8 is_gpio;
7656 u8 cfg_sts;
7657 u8 gpio_data_size;
7658 struct msm_sdcc_gpio *gpio_data;
7659 struct msm_sdcc_pad_drv_cfg *pad_drv_on_data;
7660 struct msm_sdcc_pad_drv_cfg *pad_drv_off_data;
7661 struct msm_sdcc_pad_pull_cfg *pad_pull_on_data;
7662 struct msm_sdcc_pad_pull_cfg *pad_pull_off_data;
7663 u8 pad_drv_data_size;
7664 u8 pad_pull_data_size;
7665 u8 sdio_lpm_gpio_cfg;
7666};
7667
7668
7669static struct msm_sdcc_pin_cfg sdcc_pin_cfg_data[MAX_SDCC_CONTROLLER] = {
7670#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
7671 [0] = {
7672 .is_gpio = 1,
7673 .gpio_data_size = ARRAY_SIZE(sdc1_gpio_cfg),
7674 .gpio_data = sdc1_gpio_cfg
7675 },
7676#endif
7677#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
7678 [1] = {
7679 .is_gpio = 1,
7680 .gpio_data_size = ARRAY_SIZE(sdc2_gpio_cfg),
7681 .gpio_data = sdc2_gpio_cfg
7682 },
7683#endif
7684#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
7685 [2] = {
7686 .is_gpio = 0,
7687 .pad_drv_on_data = sdc3_pad_on_drv_cfg,
7688 .pad_drv_off_data = sdc3_pad_off_drv_cfg,
7689 .pad_pull_on_data = sdc3_pad_on_pull_cfg,
7690 .pad_pull_off_data = sdc3_pad_off_pull_cfg,
7691 .pad_drv_data_size = ARRAY_SIZE(sdc3_pad_on_drv_cfg),
7692 .pad_pull_data_size = ARRAY_SIZE(sdc3_pad_on_pull_cfg)
7693 },
7694#endif
7695#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
7696 [3] = {
7697 .is_gpio = 0,
7698 .pad_drv_on_data = sdc4_pad_on_drv_cfg,
7699 .pad_drv_off_data = sdc4_pad_off_drv_cfg,
7700 .pad_pull_on_data = sdc4_pad_on_pull_cfg,
7701 .pad_pull_off_data = sdc4_pad_off_pull_cfg,
7702 .pad_drv_data_size = ARRAY_SIZE(sdc4_pad_on_drv_cfg),
7703 .pad_pull_data_size = ARRAY_SIZE(sdc4_pad_on_pull_cfg)
7704 },
7705#endif
7706#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
7707 [4] = {
7708 .is_gpio = 1,
7709 .gpio_data_size = ARRAY_SIZE(sdc5_gpio_cfg),
7710 .gpio_data = sdc5_gpio_cfg
7711 }
7712#endif
7713};
7714
7715static int msm_sdcc_setup_gpio(int dev_id, unsigned int enable)
7716{
7717 int rc = 0;
7718 struct msm_sdcc_pin_cfg *curr;
7719 int n;
7720
7721 curr = &sdcc_pin_cfg_data[dev_id - 1];
7722 if (!curr->gpio_data)
7723 goto out;
7724
7725 for (n = 0; n < curr->gpio_data_size; n++) {
7726 if (enable) {
7727
7728 if (curr->gpio_data[n].always_on &&
7729 curr->gpio_data[n].is_enabled)
7730 continue;
7731 pr_debug("%s: enable: %s\n", __func__,
7732 curr->gpio_data[n].name);
7733 rc = gpio_request(curr->gpio_data[n].no,
7734 curr->gpio_data[n].name);
7735 if (rc) {
7736 pr_err("%s: gpio_request(%d, %s)"
7737 "failed", __func__,
7738 curr->gpio_data[n].no,
7739 curr->gpio_data[n].name);
7740 goto free_gpios;
7741 }
7742 /* set direction as output for all GPIOs */
7743 rc = gpio_direction_output(
7744 curr->gpio_data[n].no, 1);
7745 if (rc) {
7746 pr_err("%s: gpio_direction_output"
7747 "(%d, 1) failed\n", __func__,
7748 curr->gpio_data[n].no);
7749 goto free_gpios;
7750 }
7751 curr->gpio_data[n].is_enabled = 1;
7752 } else {
7753 /*
7754 * now free this GPIO which will put GPIO
7755 * in low power mode and will also put GPIO
7756 * in input mode
7757 */
7758 if (curr->gpio_data[n].always_on)
7759 continue;
7760 pr_debug("%s: disable: %s\n", __func__,
7761 curr->gpio_data[n].name);
7762 gpio_free(curr->gpio_data[n].no);
7763 curr->gpio_data[n].is_enabled = 0;
7764 }
7765 }
7766 curr->cfg_sts = enable;
7767 goto out;
7768
7769free_gpios:
7770 for (; n >= 0; n--)
7771 gpio_free(curr->gpio_data[n].no);
7772out:
7773 return rc;
7774}
7775
7776static int msm_sdcc_setup_pad(int dev_id, unsigned int enable)
7777{
7778 int rc = 0;
7779 struct msm_sdcc_pin_cfg *curr;
7780 int n;
7781
7782 curr = &sdcc_pin_cfg_data[dev_id - 1];
7783 if (!curr->pad_drv_on_data || !curr->pad_pull_on_data)
7784 goto out;
7785
7786 if (enable) {
7787 /*
7788 * set up the normal driver strength and
7789 * pull config for pads
7790 */
7791 for (n = 0; n < curr->pad_drv_data_size; n++) {
7792 if (curr->sdio_lpm_gpio_cfg) {
7793 if (curr->pad_drv_on_data[n].drv ==
7794 TLMM_HDRV_SDC4_DATA)
7795 continue;
7796 }
7797 msm_tlmm_set_hdrive(curr->pad_drv_on_data[n].drv,
7798 curr->pad_drv_on_data[n].drv_val);
7799 }
7800 for (n = 0; n < curr->pad_pull_data_size; n++) {
7801 if (curr->sdio_lpm_gpio_cfg) {
7802 if (curr->pad_pull_on_data[n].pull ==
7803 TLMM_PULL_SDC4_DATA)
7804 continue;
7805 }
7806 msm_tlmm_set_pull(curr->pad_pull_on_data[n].pull,
7807 curr->pad_pull_on_data[n].pull_val);
7808 }
7809 } else {
7810 /* set the low power config for pads */
7811 for (n = 0; n < curr->pad_drv_data_size; n++) {
7812 if (curr->sdio_lpm_gpio_cfg) {
7813 if (curr->pad_drv_off_data[n].drv ==
7814 TLMM_HDRV_SDC4_DATA)
7815 continue;
7816 }
7817 msm_tlmm_set_hdrive(
7818 curr->pad_drv_off_data[n].drv,
7819 curr->pad_drv_off_data[n].drv_val);
7820 }
7821 for (n = 0; n < curr->pad_pull_data_size; n++) {
7822 if (curr->sdio_lpm_gpio_cfg) {
7823 if (curr->pad_pull_off_data[n].pull ==
7824 TLMM_PULL_SDC4_DATA)
7825 continue;
7826 }
7827 msm_tlmm_set_pull(
7828 curr->pad_pull_off_data[n].pull,
7829 curr->pad_pull_off_data[n].pull_val);
7830 }
7831 }
7832 curr->cfg_sts = enable;
7833out:
7834 return rc;
7835}
7836
7837struct sdcc_reg {
7838 /* VDD/VCC/VCCQ regulator name on PMIC8058/PMIC8089*/
7839 const char *reg_name;
7840 /*
7841 * is set voltage supported for this regulator?
7842 * 0 = not supported, 1 = supported
7843 */
7844 unsigned char set_voltage_sup;
7845 /* voltage level to be set */
7846 unsigned int level;
7847 /* VDD/VCC/VCCQ voltage regulator handle */
7848 struct regulator *reg;
7849 /* is this regulator enabled? */
7850 bool enabled;
7851 /* is this regulator needs to be always on? */
7852 bool always_on;
7853 /* is operating power mode setting required for this regulator? */
7854 bool op_pwr_mode_sup;
7855 /* Load values for low power and high power mode */
7856 unsigned int lpm_uA;
7857 unsigned int hpm_uA;
7858};
7859/* all SDCC controllers requires VDD/VCC voltage */
7860static struct sdcc_reg sdcc_vdd_reg_data[MAX_SDCC_CONTROLLER];
7861/* only SDCC1 requires VCCQ voltage */
7862static struct sdcc_reg sdcc_vccq_reg_data[1];
7863/* all SDCC controllers may require voting for VDD PAD voltage */
7864static struct sdcc_reg sdcc_vddp_reg_data[MAX_SDCC_CONTROLLER];
7865
7866struct sdcc_reg_data {
7867 struct sdcc_reg *vdd_data; /* keeps VDD/VCC regulator info */
7868 struct sdcc_reg *vccq_data; /* keeps VCCQ regulator info */
7869 struct sdcc_reg *vddp_data; /* keeps VDD Pad regulator info */
7870 unsigned char sts; /* regulator enable/disable status */
7871};
7872/* msm8x60 have 5 SDCC controllers */
7873static struct sdcc_reg_data sdcc_vreg_data[MAX_SDCC_CONTROLLER];
7874
7875static int msm_sdcc_vreg_init_reg(struct sdcc_reg *vreg)
7876{
7877 int rc = 0;
7878
7879 /* Get the regulator handle */
7880 vreg->reg = regulator_get(NULL, vreg->reg_name);
7881 if (IS_ERR(vreg->reg)) {
7882 rc = PTR_ERR(vreg->reg);
7883 pr_err("%s: regulator_get(%s) failed. rc=%d\n",
7884 __func__, vreg->reg_name, rc);
7885 goto out;
7886 }
7887
7888 /* Set the voltage level if required */
7889 if (vreg->set_voltage_sup) {
7890 rc = regulator_set_voltage(vreg->reg, vreg->level,
7891 vreg->level);
7892 if (rc) {
7893 pr_err("%s: regulator_set_voltage(%s) failed rc=%d\n",
7894 __func__, vreg->reg_name, rc);
7895 goto vreg_put;
7896 }
7897 }
7898 goto out;
7899
7900vreg_put:
7901 regulator_put(vreg->reg);
7902out:
7903 return rc;
7904}
7905
7906static inline void msm_sdcc_vreg_deinit_reg(struct sdcc_reg *vreg)
7907{
7908 regulator_put(vreg->reg);
7909}
7910
7911/* this init function should be called only once for each SDCC */
7912static int msm_sdcc_vreg_init(int dev_id, unsigned char init)
7913{
7914 int rc = 0;
7915 struct sdcc_reg *curr_vdd_reg, *curr_vccq_reg, *curr_vddp_reg;
7916 struct sdcc_reg_data *curr;
7917
7918 curr = &sdcc_vreg_data[dev_id - 1];
7919 curr_vdd_reg = curr->vdd_data;
7920 curr_vccq_reg = curr->vccq_data;
7921 curr_vddp_reg = curr->vddp_data;
7922
7923 if (init) {
7924 /*
7925 * get the regulator handle from voltage regulator framework
7926 * and then try to set the voltage level for the regulator
7927 */
7928 if (curr_vdd_reg) {
7929 rc = msm_sdcc_vreg_init_reg(curr_vdd_reg);
7930 if (rc)
7931 goto out;
7932 }
7933 if (curr_vccq_reg) {
7934 rc = msm_sdcc_vreg_init_reg(curr_vccq_reg);
7935 if (rc)
7936 goto vdd_reg_deinit;
7937 }
7938 if (curr_vddp_reg) {
7939 rc = msm_sdcc_vreg_init_reg(curr_vddp_reg);
7940 if (rc)
7941 goto vccq_reg_deinit;
7942 }
7943 goto out;
7944 } else
7945 /* deregister with all regulators from regulator framework */
7946 goto vddp_reg_deinit;
7947
7948vddp_reg_deinit:
7949 if (curr_vddp_reg)
7950 msm_sdcc_vreg_deinit_reg(curr_vddp_reg);
7951vccq_reg_deinit:
7952 if (curr_vccq_reg)
7953 msm_sdcc_vreg_deinit_reg(curr_vccq_reg);
7954vdd_reg_deinit:
7955 if (curr_vdd_reg)
7956 msm_sdcc_vreg_deinit_reg(curr_vdd_reg);
7957out:
7958 return rc;
7959}
7960
7961static int msm_sdcc_vreg_enable(struct sdcc_reg *vreg)
7962{
7963 int rc;
7964
7965 if (!vreg->enabled) {
7966 rc = regulator_enable(vreg->reg);
7967 if (rc) {
7968 pr_err("%s: regulator_enable(%s) failed. rc=%d\n",
7969 __func__, vreg->reg_name, rc);
7970 goto out;
7971 }
7972 vreg->enabled = 1;
7973 }
7974
7975 /* Put always_on regulator in HPM (high power mode) */
7976 if (vreg->always_on && vreg->op_pwr_mode_sup) {
7977 rc = regulator_set_optimum_mode(vreg->reg, vreg->hpm_uA);
7978 if (rc < 0) {
7979 pr_err("%s: reg=%s: HPM setting failed"
7980 " hpm_uA=%d, rc=%d\n",
7981 __func__, vreg->reg_name,
7982 vreg->hpm_uA, rc);
7983 goto vreg_disable;
7984 }
7985 rc = 0;
7986 }
7987 goto out;
7988
7989vreg_disable:
7990 regulator_disable(vreg->reg);
7991 vreg->enabled = 0;
7992out:
7993 return rc;
7994}
7995
7996static int msm_sdcc_vreg_disable(struct sdcc_reg *vreg)
7997{
7998 int rc;
7999
8000 /* Never disable always_on regulator */
8001 if (!vreg->always_on) {
8002 rc = regulator_disable(vreg->reg);
8003 if (rc) {
8004 pr_err("%s: regulator_disable(%s) failed. rc=%d\n",
8005 __func__, vreg->reg_name, rc);
8006 goto out;
8007 }
8008 vreg->enabled = 0;
8009 }
8010
8011 /* Put always_on regulator in LPM (low power mode) */
8012 if (vreg->always_on && vreg->op_pwr_mode_sup) {
8013 rc = regulator_set_optimum_mode(vreg->reg, vreg->lpm_uA);
8014 if (rc < 0) {
8015 pr_err("%s: reg=%s: LPM setting failed"
8016 " lpm_uA=%d, rc=%d\n",
8017 __func__,
8018 vreg->reg_name,
8019 vreg->lpm_uA, rc);
8020 goto out;
8021 }
8022 rc = 0;
8023 }
8024
8025out:
8026 return rc;
8027}
8028
8029static int msm_sdcc_setup_vreg(int dev_id, unsigned char enable)
8030{
8031 int rc = 0;
8032 struct sdcc_reg *curr_vdd_reg, *curr_vccq_reg, *curr_vddp_reg;
8033 struct sdcc_reg_data *curr;
8034
8035 curr = &sdcc_vreg_data[dev_id - 1];
8036 curr_vdd_reg = curr->vdd_data;
8037 curr_vccq_reg = curr->vccq_data;
8038 curr_vddp_reg = curr->vddp_data;
8039
8040 /* check if regulators are initialized or not? */
8041 if ((curr_vdd_reg && !curr_vdd_reg->reg) ||
8042 (curr_vccq_reg && !curr_vccq_reg->reg) ||
8043 (curr_vddp_reg && !curr_vddp_reg->reg)) {
8044 /* initialize voltage regulators required for this SDCC */
8045 rc = msm_sdcc_vreg_init(dev_id, 1);
8046 if (rc) {
8047 pr_err("%s: regulator init failed = %d\n",
8048 __func__, rc);
8049 goto out;
8050 }
8051 }
8052
8053 if (curr->sts == enable)
8054 goto out;
8055
8056 if (curr_vdd_reg) {
8057 if (enable)
8058 rc = msm_sdcc_vreg_enable(curr_vdd_reg);
8059 else
8060 rc = msm_sdcc_vreg_disable(curr_vdd_reg);
8061 if (rc)
8062 goto out;
8063 }
8064
8065 if (curr_vccq_reg) {
8066 if (enable)
8067 rc = msm_sdcc_vreg_enable(curr_vccq_reg);
8068 else
8069 rc = msm_sdcc_vreg_disable(curr_vccq_reg);
8070 if (rc)
8071 goto out;
8072 }
8073
8074 if (curr_vddp_reg) {
8075 if (enable)
8076 rc = msm_sdcc_vreg_enable(curr_vddp_reg);
8077 else
8078 rc = msm_sdcc_vreg_disable(curr_vddp_reg);
8079 if (rc)
8080 goto out;
8081 }
8082 curr->sts = enable;
8083
8084out:
8085 return rc;
8086}
8087
8088static u32 msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
8089{
8090 u32 rc_pin_cfg = 0;
8091 u32 rc_vreg_cfg = 0;
8092 u32 rc = 0;
8093 struct platform_device *pdev;
8094 struct msm_sdcc_pin_cfg *curr_pin_cfg;
8095
8096 pdev = container_of(dv, struct platform_device, dev);
8097
8098 /* setup gpio/pad */
8099 curr_pin_cfg = &sdcc_pin_cfg_data[pdev->id - 1];
8100 if (curr_pin_cfg->cfg_sts == !!vdd)
8101 goto setup_vreg;
8102
8103 if (curr_pin_cfg->is_gpio)
8104 rc_pin_cfg = msm_sdcc_setup_gpio(pdev->id, !!vdd);
8105 else
8106 rc_pin_cfg = msm_sdcc_setup_pad(pdev->id, !!vdd);
8107
8108setup_vreg:
8109 /* setup voltage regulators */
8110 rc_vreg_cfg = msm_sdcc_setup_vreg(pdev->id, !!vdd);
8111
8112 if (rc_pin_cfg || rc_vreg_cfg)
8113 rc = rc_pin_cfg ? rc_pin_cfg : rc_vreg_cfg;
8114
8115 return rc;
8116}
8117
8118static void msm_sdcc_sdio_lpm_gpio(struct device *dv, unsigned int active)
8119{
8120 struct msm_sdcc_pin_cfg *curr_pin_cfg;
8121 struct platform_device *pdev;
8122
8123 pdev = container_of(dv, struct platform_device, dev);
8124 /* setup gpio/pad */
8125 curr_pin_cfg = &sdcc_pin_cfg_data[pdev->id - 1];
8126
8127 if (curr_pin_cfg->cfg_sts == active)
8128 return;
8129
8130 curr_pin_cfg->sdio_lpm_gpio_cfg = 1;
8131 if (curr_pin_cfg->is_gpio)
8132 msm_sdcc_setup_gpio(pdev->id, active);
8133 else
8134 msm_sdcc_setup_pad(pdev->id, active);
8135 curr_pin_cfg->sdio_lpm_gpio_cfg = 0;
8136}
8137
8138static int msm_sdc3_get_wpswitch(struct device *dev)
8139{
8140 struct platform_device *pdev;
8141 int status;
8142 pdev = container_of(dev, struct platform_device, dev);
8143
8144 status = gpio_request(GPIO_SDC_WP, "SD_WP_Switch");
8145 if (status) {
8146 pr_err("%s:Failed to request GPIO %d\n",
8147 __func__, GPIO_SDC_WP);
8148 } else {
8149 status = gpio_direction_input(GPIO_SDC_WP);
8150 if (!status) {
8151 status = gpio_get_value_cansleep(GPIO_SDC_WP);
8152 pr_info("%s: WP Status for Slot %d = %d\n",
8153 __func__, pdev->id, status);
8154 }
8155 gpio_free(GPIO_SDC_WP);
8156 }
8157 return status;
8158}
8159
8160#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
8161int sdc5_register_status_notify(void (*callback)(int, void *),
8162 void *dev_id)
8163{
8164 sdc5_status_notify_cb = callback;
8165 sdc5_status_notify_cb_devid = dev_id;
8166 return 0;
8167}
8168#endif
8169
8170#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
8171int sdc2_register_status_notify(void (*callback)(int, void *),
8172 void *dev_id)
8173{
8174 sdc2_status_notify_cb = callback;
8175 sdc2_status_notify_cb_devid = dev_id;
8176 return 0;
8177}
8178#endif
8179
8180/* Interrupt handler for SDC2 and SDC5 detection
8181 * This function uses dual-edge interrputs settings in order
8182 * to get SDIO detection when the GPIO is rising and SDIO removal
8183 * when the GPIO is falling */
8184static irqreturn_t msm8x60_multi_sdio_slot_status_irq(int irq, void *dev_id)
8185{
8186 int status;
8187
8188 if (!machine_is_msm8x60_fusion() &&
8189 !machine_is_msm8x60_fusn_ffa())
8190 return IRQ_NONE;
8191
8192 status = gpio_get_value(MDM2AP_SYNC);
8193 pr_info("%s: MDM2AP_SYNC Status = %d\n",
8194 __func__, status);
8195
8196#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
8197 if (sdc2_status_notify_cb) {
8198 pr_info("%s: calling sdc2_status_notify_cb\n", __func__);
8199 sdc2_status_notify_cb(status,
8200 sdc2_status_notify_cb_devid);
8201 }
8202#endif
8203
8204#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
8205 if (sdc5_status_notify_cb) {
8206 pr_info("%s: calling sdc5_status_notify_cb\n", __func__);
8207 sdc5_status_notify_cb(status,
8208 sdc5_status_notify_cb_devid);
8209 }
8210#endif
8211 return IRQ_HANDLED;
8212}
8213
8214static int msm8x60_multi_sdio_init(void)
8215{
8216 int ret, irq_num;
8217
8218 if (!machine_is_msm8x60_fusion() &&
8219 !machine_is_msm8x60_fusn_ffa())
8220 return 0;
8221
8222 ret = msm_gpiomux_get(MDM2AP_SYNC);
8223 if (ret) {
8224 pr_err("%s:Failed to request GPIO %d, ret=%d\n",
8225 __func__, MDM2AP_SYNC, ret);
8226 return ret;
8227 }
8228
8229 irq_num = gpio_to_irq(MDM2AP_SYNC);
8230
8231 ret = request_irq(irq_num,
8232 msm8x60_multi_sdio_slot_status_irq,
8233 IRQ_TYPE_EDGE_BOTH,
8234 "sdio_multidetection", NULL);
8235
8236 if (ret) {
8237 pr_err("%s:Failed to request irq, ret=%d\n",
8238 __func__, ret);
8239 return ret;
8240 }
8241
8242 return ret;
8243}
8244
8245#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
8246#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
8247static unsigned int msm8x60_sdcc_slot_status(struct device *dev)
8248{
8249 int status;
8250
8251 status = gpio_request(PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1)
8252 , "SD_HW_Detect");
8253 if (status) {
8254 pr_err("%s:Failed to request GPIO %d\n", __func__,
8255 PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1));
8256 } else {
8257 status = gpio_direction_input(
8258 PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1));
8259 if (!status)
8260 status = !(gpio_get_value_cansleep(
8261 PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1)));
8262 gpio_free(PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1));
8263 }
8264 return (unsigned int) status;
8265}
8266#endif
8267#endif
8268
8269#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
8270static int msm_sdcc_cfg_mpm_sdiowakeup(struct device *dev, unsigned mode)
8271{
8272 struct platform_device *pdev;
8273 enum msm_mpm_pin pin;
8274 int ret = 0;
8275
8276 pdev = container_of(dev, struct platform_device, dev);
8277
8278 /* Only SDCC4 slot connected to WLAN chip has wakeup capability */
8279 if (pdev->id == 4)
8280 pin = MSM_MPM_PIN_SDC4_DAT1;
8281 else
8282 return -EINVAL;
8283
8284 switch (mode) {
8285 case SDC_DAT1_DISABLE:
8286 ret = msm_mpm_enable_pin(pin, 0);
8287 break;
8288 case SDC_DAT1_ENABLE:
8289 ret = msm_mpm_set_pin_type(pin, IRQ_TYPE_LEVEL_LOW);
8290 ret = msm_mpm_enable_pin(pin, 1);
8291 break;
8292 case SDC_DAT1_ENWAKE:
8293 ret = msm_mpm_set_pin_wake(pin, 1);
8294 break;
8295 case SDC_DAT1_DISWAKE:
8296 ret = msm_mpm_set_pin_wake(pin, 0);
8297 break;
8298 default:
8299 ret = -EINVAL;
8300 break;
8301 }
8302 return ret;
8303}
8304#endif
8305#endif
8306
8307#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
8308static struct mmc_platform_data msm8x60_sdc1_data = {
8309 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
8310 .translate_vdd = msm_sdcc_setup_power,
8311#ifdef CONFIG_MMC_MSM_SDC1_8_BIT_SUPPORT
8312 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
8313#else
8314 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
8315#endif
8316 .msmsdcc_fmin = 400000,
8317 .msmsdcc_fmid = 24000000,
8318 .msmsdcc_fmax = 48000000,
8319 .nonremovable = 1,
8320 .pclk_src_dfab = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008321};
8322#endif
8323
8324#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
8325static struct mmc_platform_data msm8x60_sdc2_data = {
8326 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_165_195,
8327 .translate_vdd = msm_sdcc_setup_power,
8328 .sdio_lpm_gpio_setup = msm_sdcc_sdio_lpm_gpio,
8329 .mmc_bus_width = MMC_CAP_8_BIT_DATA,
8330 .msmsdcc_fmin = 400000,
8331 .msmsdcc_fmid = 24000000,
8332 .msmsdcc_fmax = 48000000,
8333 .nonremovable = 0,
8334 .pclk_src_dfab = 1,
8335 .register_status_notify = sdc2_register_status_notify,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008336#ifdef CONFIG_MSM_SDIO_AL
8337 .is_sdio_al_client = 1,
8338#endif
8339};
8340#endif
8341
8342#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
8343static struct mmc_platform_data msm8x60_sdc3_data = {
8344 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
8345 .translate_vdd = msm_sdcc_setup_power,
8346 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
8347 .wpswitch = msm_sdc3_get_wpswitch,
8348#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
8349 .status = msm8x60_sdcc_slot_status,
8350 .status_irq = PM8058_GPIO_IRQ(PM8058_IRQ_BASE,
8351 PMIC_GPIO_SDC3_DET - 1),
8352 .irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
8353#endif
8354 .msmsdcc_fmin = 400000,
8355 .msmsdcc_fmid = 24000000,
8356 .msmsdcc_fmax = 48000000,
8357 .nonremovable = 0,
8358 .pclk_src_dfab = 1,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008359};
8360#endif
8361
8362#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
8363static struct mmc_platform_data msm8x60_sdc4_data = {
8364 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
8365 .translate_vdd = msm_sdcc_setup_power,
8366 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
8367 .msmsdcc_fmin = 400000,
8368 .msmsdcc_fmid = 24000000,
8369 .msmsdcc_fmax = 48000000,
8370 .nonremovable = 0,
8371 .pclk_src_dfab = 1,
8372 .cfg_mpm_sdiowakeup = msm_sdcc_cfg_mpm_sdiowakeup,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008373};
8374#endif
8375
8376#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
8377static struct mmc_platform_data msm8x60_sdc5_data = {
8378 .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_165_195,
8379 .translate_vdd = msm_sdcc_setup_power,
8380 .sdio_lpm_gpio_setup = msm_sdcc_sdio_lpm_gpio,
8381 .mmc_bus_width = MMC_CAP_4_BIT_DATA,
8382 .msmsdcc_fmin = 400000,
8383 .msmsdcc_fmid = 24000000,
8384 .msmsdcc_fmax = 48000000,
8385 .nonremovable = 0,
8386 .pclk_src_dfab = 1,
8387 .register_status_notify = sdc5_register_status_notify,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008388#ifdef CONFIG_MSM_SDIO_AL
8389 .is_sdio_al_client = 1,
8390#endif
8391};
8392#endif
8393
8394static void __init msm8x60_init_mmc(void)
8395{
8396#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
8397 /* SDCC1 : eMMC card connected */
8398 sdcc_vreg_data[0].vdd_data = &sdcc_vdd_reg_data[0];
8399 sdcc_vreg_data[0].vdd_data->reg_name = "8901_l5";
8400 sdcc_vreg_data[0].vdd_data->set_voltage_sup = 1;
8401 sdcc_vreg_data[0].vdd_data->level = 2850000;
Subhash Jadavania8482a32011-08-08 11:01:44 +05308402 sdcc_vreg_data[0].vdd_data->always_on = 1;
8403 sdcc_vreg_data[0].vdd_data->op_pwr_mode_sup = 1;
8404 sdcc_vreg_data[0].vdd_data->lpm_uA = 9000;
8405 sdcc_vreg_data[0].vdd_data->hpm_uA = 200000;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008406
8407 sdcc_vreg_data[0].vccq_data = &sdcc_vccq_reg_data[0];
8408 sdcc_vreg_data[0].vccq_data->reg_name = "8901_lvs0";
8409 sdcc_vreg_data[0].vccq_data->set_voltage_sup = 0;
8410 sdcc_vreg_data[0].vccq_data->always_on = 1;
8411
8412 msm_add_sdcc(1, &msm8x60_sdc1_data);
8413#endif
8414#ifdef CONFIG_MMC_MSM_SDC2_SUPPORT
8415 /*
8416 * MDM SDIO client is connected to SDC2 on charm SURF/FFA
8417 * and no card is connected on 8660 SURF/FFA/FLUID.
8418 */
8419 sdcc_vreg_data[1].vdd_data = &sdcc_vdd_reg_data[1];
8420 sdcc_vreg_data[1].vdd_data->reg_name = "8058_s3";
8421 sdcc_vreg_data[1].vdd_data->set_voltage_sup = 1;
8422 sdcc_vreg_data[1].vdd_data->level = 1800000;
8423
8424 sdcc_vreg_data[1].vccq_data = NULL;
8425
8426 if (machine_is_msm8x60_fusion())
8427 msm8x60_sdc2_data.msmsdcc_fmax = 24000000;
8428 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
8429#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
8430 msm8x60_sdc2_data.sdiowakeup_irq = gpio_to_irq(144);
8431 msm_sdcc_setup_gpio(2, 1);
8432#endif
8433 msm_add_sdcc(2, &msm8x60_sdc2_data);
8434 }
8435#endif
8436#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
8437 /* SDCC3 : External card slot connected */
8438 sdcc_vreg_data[2].vdd_data = &sdcc_vdd_reg_data[2];
8439 sdcc_vreg_data[2].vdd_data->reg_name = "8058_l14";
8440 sdcc_vreg_data[2].vdd_data->set_voltage_sup = 1;
8441 sdcc_vreg_data[2].vdd_data->level = 2850000;
8442 sdcc_vreg_data[2].vdd_data->always_on = 1;
8443 sdcc_vreg_data[2].vdd_data->op_pwr_mode_sup = 1;
8444 sdcc_vreg_data[2].vdd_data->lpm_uA = 9000;
8445 sdcc_vreg_data[2].vdd_data->hpm_uA = 200000;
8446
8447 sdcc_vreg_data[2].vccq_data = NULL;
8448
8449 sdcc_vreg_data[2].vddp_data = &sdcc_vddp_reg_data[2];
8450 sdcc_vreg_data[2].vddp_data->reg_name = "8058_l5";
8451 sdcc_vreg_data[2].vddp_data->set_voltage_sup = 1;
8452 sdcc_vreg_data[2].vddp_data->level = 2850000;
8453 sdcc_vreg_data[2].vddp_data->always_on = 1;
8454 sdcc_vreg_data[2].vddp_data->op_pwr_mode_sup = 1;
8455 /* Sleep current required is ~300 uA. But min. RPM
8456 * vote can be in terms of mA (min. 1 mA).
8457 * So let's vote for 2 mA during sleep.
8458 */
8459 sdcc_vreg_data[2].vddp_data->lpm_uA = 2000;
8460 /* Max. Active current required is 16 mA */
8461 sdcc_vreg_data[2].vddp_data->hpm_uA = 16000;
8462
8463 if (machine_is_msm8x60_fluid())
8464 msm8x60_sdc3_data.wpswitch = NULL;
8465 msm_add_sdcc(3, &msm8x60_sdc3_data);
8466#endif
8467#ifdef CONFIG_MMC_MSM_SDC4_SUPPORT
8468 /* SDCC4 : WLAN WCN1314 chip is connected */
8469 sdcc_vreg_data[3].vdd_data = &sdcc_vdd_reg_data[3];
8470 sdcc_vreg_data[3].vdd_data->reg_name = "8058_s3";
8471 sdcc_vreg_data[3].vdd_data->set_voltage_sup = 1;
8472 sdcc_vreg_data[3].vdd_data->level = 1800000;
8473
8474 sdcc_vreg_data[3].vccq_data = NULL;
8475
8476 msm_add_sdcc(4, &msm8x60_sdc4_data);
8477#endif
8478#ifdef CONFIG_MMC_MSM_SDC5_SUPPORT
8479 /*
8480 * MDM SDIO client is connected to SDC5 on charm SURF/FFA
8481 * and no card is connected on 8660 SURF/FFA/FLUID.
8482 */
8483 sdcc_vreg_data[4].vdd_data = &sdcc_vdd_reg_data[4];
8484 sdcc_vreg_data[4].vdd_data->reg_name = "8058_s3";
8485 sdcc_vreg_data[4].vdd_data->set_voltage_sup = 1;
8486 sdcc_vreg_data[4].vdd_data->level = 1800000;
8487
8488 sdcc_vreg_data[4].vccq_data = NULL;
8489
8490 if (machine_is_msm8x60_fusion())
8491 msm8x60_sdc5_data.msmsdcc_fmax = 24000000;
8492 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
8493#ifdef CONFIG_MMC_MSM_SDIO_SUPPORT
8494 msm8x60_sdc5_data.sdiowakeup_irq = gpio_to_irq(99);
8495 msm_sdcc_setup_gpio(5, 1);
8496#endif
8497 msm_add_sdcc(5, &msm8x60_sdc5_data);
8498 }
8499#endif
8500}
8501
8502#if !defined(CONFIG_GPIO_SX150X) && !defined(CONFIG_GPIO_SX150X_MODULE)
8503static inline void display_common_power(int on) {}
8504#else
8505
8506#define _GET_REGULATOR(var, name) do { \
8507 if (var == NULL) { \
8508 var = regulator_get(NULL, name); \
8509 if (IS_ERR(var)) { \
8510 pr_err("'%s' regulator not found, rc=%ld\n", \
8511 name, PTR_ERR(var)); \
8512 var = NULL; \
8513 } \
8514 } \
8515} while (0)
8516
8517static int dsub_regulator(int on)
8518{
8519 static struct regulator *dsub_reg;
8520 static struct regulator *mpp0_reg;
8521 static int dsub_reg_enabled;
8522 int rc = 0;
8523
8524 _GET_REGULATOR(dsub_reg, "8901_l3");
8525 if (IS_ERR(dsub_reg)) {
8526 printk(KERN_ERR "%s: failed to get reg 8901_l3 err=%ld",
8527 __func__, PTR_ERR(dsub_reg));
8528 return PTR_ERR(dsub_reg);
8529 }
8530
8531 _GET_REGULATOR(mpp0_reg, "8901_mpp0");
8532 if (IS_ERR(mpp0_reg)) {
8533 printk(KERN_ERR "%s: failed to get reg 8901_mpp0 err=%ld",
8534 __func__, PTR_ERR(mpp0_reg));
8535 return PTR_ERR(mpp0_reg);
8536 }
8537
8538 if (on && !dsub_reg_enabled) {
8539 rc = regulator_set_voltage(dsub_reg, 3300000, 3300000);
8540 if (rc) {
8541 printk(KERN_ERR "%s: failed to set reg 8901_l3 voltage"
8542 " err=%d", __func__, rc);
8543 goto dsub_regulator_err;
8544 }
8545 rc = regulator_enable(dsub_reg);
8546 if (rc) {
8547 printk(KERN_ERR "%s: failed to enable reg 8901_l3"
8548 " err=%d", __func__, rc);
8549 goto dsub_regulator_err;
8550 }
8551 rc = regulator_enable(mpp0_reg);
8552 if (rc) {
8553 printk(KERN_ERR "%s: failed to enable reg 8901_mpp0"
8554 " err=%d", __func__, rc);
8555 goto dsub_regulator_err;
8556 }
8557 dsub_reg_enabled = 1;
8558 } else if (!on && dsub_reg_enabled) {
8559 rc = regulator_disable(dsub_reg);
8560 if (rc)
8561 printk(KERN_WARNING "%s: failed to disable reg 8901_l3"
8562 " err=%d", __func__, rc);
8563 rc = regulator_disable(mpp0_reg);
8564 if (rc)
8565 printk(KERN_WARNING "%s: failed to disable reg "
8566 "8901_mpp0 err=%d", __func__, rc);
8567 dsub_reg_enabled = 0;
8568 }
8569
8570 return rc;
8571
8572dsub_regulator_err:
8573 regulator_put(mpp0_reg);
8574 regulator_put(dsub_reg);
8575 return rc;
8576}
8577
8578static int display_power_on;
8579static void setup_display_power(void)
8580{
8581 if (display_power_on)
8582 if (lcdc_vga_enabled) {
8583 dsub_regulator(1);
8584 gpio_set_value_cansleep(GPIO_LVDS_SHUTDOWN_N, 0);
8585 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, 0);
8586 if (machine_is_msm8x60_ffa() ||
8587 machine_is_msm8x60_fusn_ffa())
8588 gpio_set_value_cansleep(GPIO_DONGLE_PWR_EN, 1);
8589 } else {
8590 dsub_regulator(0);
8591 gpio_set_value_cansleep(GPIO_LVDS_SHUTDOWN_N, 1);
8592 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, 1);
8593 if (machine_is_msm8x60_ffa() ||
8594 machine_is_msm8x60_fusn_ffa())
8595 gpio_set_value_cansleep(GPIO_DONGLE_PWR_EN, 0);
8596 }
8597 else {
8598 dsub_regulator(0);
8599 if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa())
8600 gpio_set_value_cansleep(GPIO_DONGLE_PWR_EN, 0);
8601 /* BACKLIGHT */
8602 gpio_set_value_cansleep(GPIO_BACKLIGHT_EN, 0);
8603 /* LVDS */
8604 gpio_set_value_cansleep(GPIO_LVDS_SHUTDOWN_N, 0);
8605 }
8606}
8607
8608#define _GET_REGULATOR(var, name) do { \
8609 if (var == NULL) { \
8610 var = regulator_get(NULL, name); \
8611 if (IS_ERR(var)) { \
8612 pr_err("'%s' regulator not found, rc=%ld\n", \
8613 name, PTR_ERR(var)); \
8614 var = NULL; \
8615 } \
8616 } \
8617} while (0)
8618
8619#define GPIO_RESX_N (GPIO_EXPANDER_GPIO_BASE + 2)
8620
8621static void display_common_power(int on)
8622{
8623 int rc;
8624 static struct regulator *display_reg;
8625
8626 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
8627 machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
8628 if (on) {
8629 /* LVDS */
8630 _GET_REGULATOR(display_reg, "8901_l2");
8631 if (!display_reg)
8632 return;
8633 rc = regulator_set_voltage(display_reg,
8634 3300000, 3300000);
8635 if (rc)
8636 goto out;
8637 rc = regulator_enable(display_reg);
8638 if (rc)
8639 goto out;
8640 rc = gpio_request(GPIO_LVDS_SHUTDOWN_N,
8641 "LVDS_STDN_OUT_N");
8642 if (rc) {
8643 printk(KERN_ERR "%s: LVDS gpio %d request"
8644 "failed\n", __func__,
8645 GPIO_LVDS_SHUTDOWN_N);
8646 goto out2;
8647 }
8648
8649 /* BACKLIGHT */
8650 rc = gpio_request(GPIO_BACKLIGHT_EN, "BACKLIGHT_EN");
8651 if (rc) {
8652 printk(KERN_ERR "%s: BACKLIGHT gpio %d request"
8653 "failed\n", __func__,
8654 GPIO_BACKLIGHT_EN);
8655 goto out3;
8656 }
8657
8658 if (machine_is_msm8x60_ffa() ||
8659 machine_is_msm8x60_fusn_ffa()) {
8660 rc = gpio_request(GPIO_DONGLE_PWR_EN,
8661 "DONGLE_PWR_EN");
8662 if (rc) {
8663 printk(KERN_ERR "%s: DONGLE_PWR_EN gpio"
8664 " %d request failed\n", __func__,
8665 GPIO_DONGLE_PWR_EN);
8666 goto out4;
8667 }
8668 }
8669
8670 gpio_direction_output(GPIO_LVDS_SHUTDOWN_N, 0);
8671 gpio_direction_output(GPIO_BACKLIGHT_EN, 0);
8672 if (machine_is_msm8x60_ffa() ||
8673 machine_is_msm8x60_fusn_ffa())
8674 gpio_direction_output(GPIO_DONGLE_PWR_EN, 0);
8675 mdelay(20);
8676 display_power_on = 1;
8677 setup_display_power();
8678 } else {
8679 if (display_power_on) {
8680 display_power_on = 0;
8681 setup_display_power();
8682 mdelay(20);
8683 if (machine_is_msm8x60_ffa() ||
8684 machine_is_msm8x60_fusn_ffa())
8685 gpio_free(GPIO_DONGLE_PWR_EN);
8686 goto out4;
8687 }
8688 }
8689 }
8690#if defined(CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT) || \
8691 defined(CONFIG_FB_MSM_LCDC_AUO_WVGA)
8692 else if (machine_is_msm8x60_fluid()) {
8693 static struct regulator *fluid_reg;
8694 static struct regulator *fluid_reg2;
8695
8696 if (on) {
8697 _GET_REGULATOR(fluid_reg, "8901_l2");
8698 if (!fluid_reg)
8699 return;
8700 _GET_REGULATOR(fluid_reg2, "8058_s3");
8701 if (!fluid_reg2) {
8702 regulator_put(fluid_reg);
8703 return;
8704 }
8705 rc = gpio_request(GPIO_RESX_N, "RESX_N");
8706 if (rc) {
8707 regulator_put(fluid_reg2);
8708 regulator_put(fluid_reg);
8709 return;
8710 }
8711 regulator_set_voltage(fluid_reg, 2850000, 2850000);
8712 regulator_set_voltage(fluid_reg2, 1800000, 1800000);
8713 regulator_enable(fluid_reg);
8714 regulator_enable(fluid_reg2);
8715 msleep(20);
8716 gpio_direction_output(GPIO_RESX_N, 0);
8717 udelay(10);
8718 gpio_set_value_cansleep(GPIO_RESX_N, 1);
8719 display_power_on = 1;
8720 setup_display_power();
8721 } else {
8722 gpio_set_value_cansleep(GPIO_RESX_N, 0);
8723 gpio_free(GPIO_RESX_N);
8724 msleep(20);
8725 regulator_disable(fluid_reg2);
8726 regulator_disable(fluid_reg);
8727 regulator_put(fluid_reg2);
8728 regulator_put(fluid_reg);
8729 display_power_on = 0;
8730 setup_display_power();
8731 fluid_reg = NULL;
8732 fluid_reg2 = NULL;
8733 }
8734 }
8735#endif
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -04008736#if defined(CONFIG_FB_MSM_LCDC_NT35582_WVGA)
8737 else if (machine_is_msm8x60_dragon()) {
8738 static struct regulator *dragon_reg;
8739 static struct regulator *dragon_reg2;
8740
8741 if (on) {
8742 _GET_REGULATOR(dragon_reg, "8901_l2");
8743 if (!dragon_reg)
8744 return;
8745 _GET_REGULATOR(dragon_reg2, "8058_l16");
8746 if (!dragon_reg2) {
8747 regulator_put(dragon_reg);
8748 dragon_reg = NULL;
8749 return;
8750 }
8751
8752 rc = gpio_request(GPIO_NT35582_BL_EN, "lcdc_bl_en");
8753 if (rc) {
8754 pr_err("%s: gpio %d request failed with rc=%d\n",
8755 __func__, GPIO_NT35582_BL_EN, rc);
8756 regulator_put(dragon_reg);
8757 regulator_put(dragon_reg2);
8758 dragon_reg = NULL;
8759 dragon_reg2 = NULL;
8760 return;
8761 }
8762
8763 if (gpio_tlmm_config(GPIO_CFG(GPIO_NT35582_RESET, 0,
8764 GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
8765 GPIO_CFG_16MA), GPIO_CFG_ENABLE)) {
8766 pr_err("%s: config gpio '%d' failed!\n",
8767 __func__, GPIO_NT35582_RESET);
8768 gpio_free(GPIO_NT35582_BL_EN);
8769 regulator_put(dragon_reg);
8770 regulator_put(dragon_reg2);
8771 dragon_reg = NULL;
8772 dragon_reg2 = NULL;
8773 return;
8774 }
8775
8776 rc = gpio_request(GPIO_NT35582_RESET, "lcdc_reset");
8777 if (rc) {
8778 pr_err("%s: unable to request gpio %d (rc=%d)\n",
8779 __func__, GPIO_NT35582_RESET, rc);
8780 gpio_free(GPIO_NT35582_BL_EN);
8781 regulator_put(dragon_reg);
8782 regulator_put(dragon_reg2);
8783 dragon_reg = NULL;
8784 dragon_reg2 = NULL;
8785 return;
8786 }
8787
8788 regulator_set_voltage(dragon_reg, 3300000, 3300000);
8789 regulator_set_voltage(dragon_reg2, 1800000, 1800000);
8790 regulator_enable(dragon_reg);
8791 regulator_enable(dragon_reg2);
8792 msleep(20);
8793
8794 gpio_set_value_cansleep(GPIO_NT35582_RESET, 1);
8795 msleep(20);
8796 gpio_set_value_cansleep(GPIO_NT35582_RESET, 0);
8797 msleep(20);
8798 gpio_set_value_cansleep(GPIO_NT35582_RESET, 1);
8799 msleep(50);
8800
8801 gpio_set_value_cansleep(GPIO_NT35582_BL_EN, 1);
8802
8803 display_power_on = 1;
8804 } else if ((dragon_reg != NULL) && (dragon_reg2 != NULL)) {
8805 gpio_free(GPIO_NT35582_RESET);
8806 gpio_free(GPIO_NT35582_BL_EN);
8807 regulator_disable(dragon_reg2);
8808 regulator_disable(dragon_reg);
8809 regulator_put(dragon_reg2);
8810 regulator_put(dragon_reg);
8811 display_power_on = 0;
8812 dragon_reg = NULL;
8813 dragon_reg2 = NULL;
8814 }
8815 }
8816#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07008817 return;
8818
8819out4:
8820 gpio_free(GPIO_BACKLIGHT_EN);
8821out3:
8822 gpio_free(GPIO_LVDS_SHUTDOWN_N);
8823out2:
8824 regulator_disable(display_reg);
8825out:
8826 regulator_put(display_reg);
8827 display_reg = NULL;
8828}
8829#undef _GET_REGULATOR
8830#endif
8831
8832static int mipi_dsi_panel_power(int on);
8833
8834#define LCDC_NUM_GPIO 28
8835#define LCDC_GPIO_START 0
8836
8837static void lcdc_samsung_panel_power(int on)
8838{
8839 int n, ret = 0;
8840
8841 display_common_power(on);
8842
8843 for (n = 0; n < LCDC_NUM_GPIO; n++) {
8844 if (on) {
8845 ret = gpio_request(LCDC_GPIO_START + n, "LCDC_GPIO");
8846 if (unlikely(ret)) {
8847 pr_err("%s not able to get gpio\n", __func__);
8848 break;
8849 }
8850 } else
8851 gpio_free(LCDC_GPIO_START + n);
8852 }
8853
8854 if (ret) {
8855 for (n--; n >= 0; n--)
8856 gpio_free(LCDC_GPIO_START + n);
8857 }
8858
8859 mipi_dsi_panel_power(0); /* set 8058_ldo0 to LPM */
8860}
8861
8862#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
8863#define _GET_REGULATOR(var, name) do { \
8864 var = regulator_get(NULL, name); \
8865 if (IS_ERR(var)) { \
8866 pr_err("'%s' regulator not found, rc=%ld\n", \
8867 name, IS_ERR(var)); \
8868 var = NULL; \
8869 return -ENODEV; \
8870 } \
8871} while (0)
8872
8873static int hdmi_enable_5v(int on)
8874{
8875 static struct regulator *reg_8901_hdmi_mvs; /* HDMI_5V */
8876 static struct regulator *reg_8901_mpp0; /* External 5V */
8877 static int prev_on;
8878 int rc;
8879
8880 if (on == prev_on)
8881 return 0;
8882
8883 if (!reg_8901_hdmi_mvs)
8884 _GET_REGULATOR(reg_8901_hdmi_mvs, "8901_hdmi_mvs");
8885 if (!reg_8901_mpp0)
8886 _GET_REGULATOR(reg_8901_mpp0, "8901_mpp0");
8887
8888 if (on) {
8889 rc = regulator_enable(reg_8901_mpp0);
8890 if (rc) {
8891 pr_err("'%s' regulator enable failed, rc=%d\n",
8892 "reg_8901_mpp0", rc);
8893 return rc;
8894 }
8895 rc = regulator_enable(reg_8901_hdmi_mvs);
8896 if (rc) {
8897 pr_err("'%s' regulator enable failed, rc=%d\n",
8898 "8901_hdmi_mvs", rc);
8899 return rc;
8900 }
8901 pr_info("%s(on): success\n", __func__);
8902 } else {
8903 rc = regulator_disable(reg_8901_hdmi_mvs);
8904 if (rc)
8905 pr_warning("'%s' regulator disable failed, rc=%d\n",
8906 "8901_hdmi_mvs", rc);
8907 rc = regulator_disable(reg_8901_mpp0);
8908 if (rc)
8909 pr_warning("'%s' regulator disable failed, rc=%d\n",
8910 "reg_8901_mpp0", rc);
8911 pr_info("%s(off): success\n", __func__);
8912 }
8913
8914 prev_on = on;
8915
8916 return 0;
8917}
8918
8919static int hdmi_core_power(int on, int show)
8920{
8921 static struct regulator *reg_8058_l16; /* VDD_HDMI */
8922 static int prev_on;
8923 int rc;
8924
8925 if (on == prev_on)
8926 return 0;
8927
8928 if (!reg_8058_l16)
8929 _GET_REGULATOR(reg_8058_l16, "8058_l16");
8930
8931 if (on) {
8932 rc = regulator_set_voltage(reg_8058_l16, 1800000, 1800000);
8933 if (!rc)
8934 rc = regulator_enable(reg_8058_l16);
8935 if (rc) {
8936 pr_err("'%s' regulator enable failed, rc=%d\n",
8937 "8058_l16", rc);
8938 return rc;
8939 }
8940 rc = gpio_request(170, "HDMI_DDC_CLK");
8941 if (rc) {
8942 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
8943 "HDMI_DDC_CLK", 170, rc);
8944 goto error1;
8945 }
8946 rc = gpio_request(171, "HDMI_DDC_DATA");
8947 if (rc) {
8948 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
8949 "HDMI_DDC_DATA", 171, rc);
8950 goto error2;
8951 }
8952 rc = gpio_request(172, "HDMI_HPD");
8953 if (rc) {
8954 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
8955 "HDMI_HPD", 172, rc);
8956 goto error3;
8957 }
8958 pr_info("%s(on): success\n", __func__);
8959 } else {
8960 gpio_free(170);
8961 gpio_free(171);
8962 gpio_free(172);
8963 rc = regulator_disable(reg_8058_l16);
8964 if (rc)
8965 pr_warning("'%s' regulator disable failed, rc=%d\n",
8966 "8058_l16", rc);
8967 pr_info("%s(off): success\n", __func__);
8968 }
8969
8970 prev_on = on;
8971
8972 return 0;
8973
8974error3:
8975 gpio_free(171);
8976error2:
8977 gpio_free(170);
8978error1:
8979 regulator_disable(reg_8058_l16);
8980 return rc;
8981}
8982
8983static int hdmi_cec_power(int on)
8984{
8985 static struct regulator *reg_8901_l3; /* HDMI_CEC */
8986 static int prev_on;
8987 int rc;
8988
8989 if (on == prev_on)
8990 return 0;
8991
8992 if (!reg_8901_l3)
8993 _GET_REGULATOR(reg_8901_l3, "8901_l3");
8994
8995 if (on) {
8996 rc = regulator_set_voltage(reg_8901_l3, 3300000, 3300000);
8997 if (!rc)
8998 rc = regulator_enable(reg_8901_l3);
8999 if (rc) {
9000 pr_err("'%s' regulator enable failed, rc=%d\n",
9001 "8901_l3", rc);
9002 return rc;
9003 }
9004 rc = gpio_request(169, "HDMI_CEC_VAR");
9005 if (rc) {
9006 pr_err("'%s'(%d) gpio_request failed, rc=%d\n",
9007 "HDMI_CEC_VAR", 169, rc);
9008 goto error;
9009 }
9010 pr_info("%s(on): success\n", __func__);
9011 } else {
9012 gpio_free(169);
9013 rc = regulator_disable(reg_8901_l3);
9014 if (rc)
9015 pr_warning("'%s' regulator disable failed, rc=%d\n",
9016 "8901_l3", rc);
9017 pr_info("%s(off): success\n", __func__);
9018 }
9019
9020 prev_on = on;
9021
9022 return 0;
9023error:
9024 regulator_disable(reg_8901_l3);
9025 return rc;
9026}
9027
9028#undef _GET_REGULATOR
9029
9030#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL */
9031
9032static int lcdc_panel_power(int on)
9033{
9034 int flag_on = !!on;
9035 static int lcdc_power_save_on;
9036
9037 if (lcdc_power_save_on == flag_on)
9038 return 0;
9039
9040 lcdc_power_save_on = flag_on;
9041
9042 lcdc_samsung_panel_power(on);
9043
9044 return 0;
9045}
9046
9047#ifdef CONFIG_MSM_BUS_SCALING
9048#ifdef CONFIG_FB_MSM_LCDC_DSUB
9049static struct msm_bus_vectors mdp_init_vectors[] = {
9050 /* For now, 0th array entry is reserved.
9051 * Please leave 0 as is and don't use it
9052 */
9053 {
9054 .src = MSM_BUS_MASTER_MDP_PORT0,
9055 .dst = MSM_BUS_SLAVE_SMI,
9056 .ab = 0,
9057 .ib = 0,
9058 },
9059 /* Master and slaves can be from different fabrics */
9060 {
9061 .src = MSM_BUS_MASTER_MDP_PORT0,
9062 .dst = MSM_BUS_SLAVE_EBI_CH0,
9063 .ab = 0,
9064 .ib = 0,
9065 },
9066};
9067
9068static struct msm_bus_vectors mdp_sd_smi_vectors[] = {
9069 /* Default case static display/UI/2d/3d if FB SMI */
9070 {
9071 .src = MSM_BUS_MASTER_MDP_PORT0,
9072 .dst = MSM_BUS_SLAVE_SMI,
9073 .ab = 388800000,
9074 .ib = 486000000,
9075 },
9076 /* Master and slaves can be from different fabrics */
9077 {
9078 .src = MSM_BUS_MASTER_MDP_PORT0,
9079 .dst = MSM_BUS_SLAVE_EBI_CH0,
9080 .ab = 0,
9081 .ib = 0,
9082 },
9083};
9084
9085static struct msm_bus_vectors mdp_sd_ebi_vectors[] = {
9086 /* Default case static display/UI/2d/3d if FB SMI */
9087 {
9088 .src = MSM_BUS_MASTER_MDP_PORT0,
9089 .dst = MSM_BUS_SLAVE_SMI,
9090 .ab = 0,
9091 .ib = 0,
9092 },
9093 /* Master and slaves can be from different fabrics */
9094 {
9095 .src = MSM_BUS_MASTER_MDP_PORT0,
9096 .dst = MSM_BUS_SLAVE_EBI_CH0,
9097 .ab = 388800000,
9098 .ib = 486000000 * 2,
9099 },
9100};
9101static struct msm_bus_vectors mdp_vga_vectors[] = {
9102 /* VGA and less video */
9103 {
9104 .src = MSM_BUS_MASTER_MDP_PORT0,
9105 .dst = MSM_BUS_SLAVE_SMI,
9106 .ab = 458092800,
9107 .ib = 572616000,
9108 },
9109 {
9110 .src = MSM_BUS_MASTER_MDP_PORT0,
9111 .dst = MSM_BUS_SLAVE_EBI_CH0,
9112 .ab = 458092800,
9113 .ib = 572616000 * 2,
9114 },
9115};
9116static struct msm_bus_vectors mdp_720p_vectors[] = {
9117 /* 720p and less video */
9118 {
9119 .src = MSM_BUS_MASTER_MDP_PORT0,
9120 .dst = MSM_BUS_SLAVE_SMI,
9121 .ab = 471744000,
9122 .ib = 589680000,
9123 },
9124 /* Master and slaves can be from different fabrics */
9125 {
9126 .src = MSM_BUS_MASTER_MDP_PORT0,
9127 .dst = MSM_BUS_SLAVE_EBI_CH0,
9128 .ab = 471744000,
9129 .ib = 589680000 * 2,
9130 },
9131};
9132
9133static struct msm_bus_vectors mdp_1080p_vectors[] = {
9134 /* 1080p and less video */
9135 {
9136 .src = MSM_BUS_MASTER_MDP_PORT0,
9137 .dst = MSM_BUS_SLAVE_SMI,
9138 .ab = 575424000,
9139 .ib = 719280000,
9140 },
9141 /* Master and slaves can be from different fabrics */
9142 {
9143 .src = MSM_BUS_MASTER_MDP_PORT0,
9144 .dst = MSM_BUS_SLAVE_EBI_CH0,
9145 .ab = 575424000,
9146 .ib = 719280000 * 2,
9147 },
9148};
9149
9150#else
9151static struct msm_bus_vectors mdp_init_vectors[] = {
9152 /* For now, 0th array entry is reserved.
9153 * Please leave 0 as is and don't use it
9154 */
9155 {
9156 .src = MSM_BUS_MASTER_MDP_PORT0,
9157 .dst = MSM_BUS_SLAVE_SMI,
9158 .ab = 0,
9159 .ib = 0,
9160 },
9161 /* Master and slaves can be from different fabrics */
9162 {
9163 .src = MSM_BUS_MASTER_MDP_PORT0,
9164 .dst = MSM_BUS_SLAVE_EBI_CH0,
9165 .ab = 0,
9166 .ib = 0,
9167 },
9168};
9169
9170static struct msm_bus_vectors mdp_sd_smi_vectors[] = {
9171 /* Default case static display/UI/2d/3d if FB SMI */
9172 {
9173 .src = MSM_BUS_MASTER_MDP_PORT0,
9174 .dst = MSM_BUS_SLAVE_SMI,
9175 .ab = 175110000,
9176 .ib = 218887500,
9177 },
9178 /* Master and slaves can be from different fabrics */
9179 {
9180 .src = MSM_BUS_MASTER_MDP_PORT0,
9181 .dst = MSM_BUS_SLAVE_EBI_CH0,
9182 .ab = 0,
9183 .ib = 0,
9184 },
9185};
9186
9187static struct msm_bus_vectors mdp_sd_ebi_vectors[] = {
9188 /* Default case static display/UI/2d/3d if FB SMI */
9189 {
9190 .src = MSM_BUS_MASTER_MDP_PORT0,
9191 .dst = MSM_BUS_SLAVE_SMI,
9192 .ab = 0,
9193 .ib = 0,
9194 },
9195 /* Master and slaves can be from different fabrics */
9196 {
9197 .src = MSM_BUS_MASTER_MDP_PORT0,
9198 .dst = MSM_BUS_SLAVE_EBI_CH0,
9199 .ab = 216000000,
9200 .ib = 270000000 * 2,
9201 },
9202};
9203static struct msm_bus_vectors mdp_vga_vectors[] = {
9204 /* VGA and less video */
9205 {
9206 .src = MSM_BUS_MASTER_MDP_PORT0,
9207 .dst = MSM_BUS_SLAVE_SMI,
9208 .ab = 216000000,
9209 .ib = 270000000,
9210 },
9211 {
9212 .src = MSM_BUS_MASTER_MDP_PORT0,
9213 .dst = MSM_BUS_SLAVE_EBI_CH0,
9214 .ab = 216000000,
9215 .ib = 270000000 * 2,
9216 },
9217};
9218
9219static struct msm_bus_vectors mdp_720p_vectors[] = {
9220 /* 720p and less video */
9221 {
9222 .src = MSM_BUS_MASTER_MDP_PORT0,
9223 .dst = MSM_BUS_SLAVE_SMI,
9224 .ab = 230400000,
9225 .ib = 288000000,
9226 },
9227 /* Master and slaves can be from different fabrics */
9228 {
9229 .src = MSM_BUS_MASTER_MDP_PORT0,
9230 .dst = MSM_BUS_SLAVE_EBI_CH0,
9231 .ab = 230400000,
9232 .ib = 288000000 * 2,
9233 },
9234};
9235
9236static struct msm_bus_vectors mdp_1080p_vectors[] = {
9237 /* 1080p and less video */
9238 {
9239 .src = MSM_BUS_MASTER_MDP_PORT0,
9240 .dst = MSM_BUS_SLAVE_SMI,
9241 .ab = 334080000,
9242 .ib = 417600000,
9243 },
9244 /* Master and slaves can be from different fabrics */
9245 {
9246 .src = MSM_BUS_MASTER_MDP_PORT0,
9247 .dst = MSM_BUS_SLAVE_EBI_CH0,
9248 .ab = 334080000,
Ravishangar Kalyanam731beb92011-07-07 18:27:32 -07009249 .ib = 550000000 * 2,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07009250 },
9251};
9252
9253#endif
9254static struct msm_bus_paths mdp_bus_scale_usecases[] = {
9255 {
9256 ARRAY_SIZE(mdp_init_vectors),
9257 mdp_init_vectors,
9258 },
9259 {
9260 ARRAY_SIZE(mdp_sd_smi_vectors),
9261 mdp_sd_smi_vectors,
9262 },
9263 {
9264 ARRAY_SIZE(mdp_sd_ebi_vectors),
9265 mdp_sd_ebi_vectors,
9266 },
9267 {
9268 ARRAY_SIZE(mdp_vga_vectors),
9269 mdp_vga_vectors,
9270 },
9271 {
9272 ARRAY_SIZE(mdp_720p_vectors),
9273 mdp_720p_vectors,
9274 },
9275 {
9276 ARRAY_SIZE(mdp_1080p_vectors),
9277 mdp_1080p_vectors,
9278 },
9279};
9280static struct msm_bus_scale_pdata mdp_bus_scale_pdata = {
9281 mdp_bus_scale_usecases,
9282 ARRAY_SIZE(mdp_bus_scale_usecases),
9283 .name = "mdp",
9284};
9285
9286#endif
9287#ifdef CONFIG_MSM_BUS_SCALING
9288static struct msm_bus_vectors dtv_bus_init_vectors[] = {
9289 /* For now, 0th array entry is reserved.
9290 * Please leave 0 as is and don't use it
9291 */
9292 {
9293 .src = MSM_BUS_MASTER_MDP_PORT0,
9294 .dst = MSM_BUS_SLAVE_SMI,
9295 .ab = 0,
9296 .ib = 0,
9297 },
9298 /* Master and slaves can be from different fabrics */
9299 {
9300 .src = MSM_BUS_MASTER_MDP_PORT0,
9301 .dst = MSM_BUS_SLAVE_EBI_CH0,
9302 .ab = 0,
9303 .ib = 0,
9304 },
9305};
9306static struct msm_bus_vectors dtv_bus_def_vectors[] = {
9307 /* For now, 0th array entry is reserved.
9308 * Please leave 0 as is and don't use it
9309 */
9310 {
9311 .src = MSM_BUS_MASTER_MDP_PORT0,
9312 .dst = MSM_BUS_SLAVE_SMI,
9313 .ab = 566092800,
9314 .ib = 707616000,
9315 },
9316 /* Master and slaves can be from different fabrics */
9317 {
9318 .src = MSM_BUS_MASTER_MDP_PORT0,
9319 .dst = MSM_BUS_SLAVE_EBI_CH0,
9320 .ab = 566092800,
9321 .ib = 707616000,
9322 },
9323};
9324static struct msm_bus_paths dtv_bus_scale_usecases[] = {
9325 {
9326 ARRAY_SIZE(dtv_bus_init_vectors),
9327 dtv_bus_init_vectors,
9328 },
9329 {
9330 ARRAY_SIZE(dtv_bus_def_vectors),
9331 dtv_bus_def_vectors,
9332 },
9333};
9334static struct msm_bus_scale_pdata dtv_bus_scale_pdata = {
9335 dtv_bus_scale_usecases,
9336 ARRAY_SIZE(dtv_bus_scale_usecases),
9337 .name = "dtv",
9338};
9339
9340static struct lcdc_platform_data dtv_pdata = {
9341 .bus_scale_table = &dtv_bus_scale_pdata,
9342};
9343#endif
9344
9345
9346static struct lcdc_platform_data lcdc_pdata = {
9347 .lcdc_power_save = lcdc_panel_power,
9348};
9349
9350
9351#define MDP_VSYNC_GPIO 28
9352
9353/*
9354 * MIPI_DSI only use 8058_LDO0 which need always on
9355 * therefore it need to be put at low power mode if
9356 * it was not used instead of turn it off.
9357 */
9358static int mipi_dsi_panel_power(int on)
9359{
9360 int flag_on = !!on;
9361 static int mipi_dsi_power_save_on;
9362 static struct regulator *ldo0;
9363 int rc = 0;
9364
9365 if (mipi_dsi_power_save_on == flag_on)
9366 return 0;
9367
9368 mipi_dsi_power_save_on = flag_on;
9369
9370 if (ldo0 == NULL) { /* init */
9371 ldo0 = regulator_get(NULL, "8058_l0");
9372 if (IS_ERR(ldo0)) {
9373 pr_debug("%s: LDO0 failed\n", __func__);
9374 rc = PTR_ERR(ldo0);
9375 return rc;
9376 }
9377
9378 rc = regulator_set_voltage(ldo0, 1200000, 1200000);
9379 if (rc)
9380 goto out;
9381
9382 rc = regulator_enable(ldo0);
9383 if (rc)
9384 goto out;
9385 }
9386
9387 if (on) {
9388 /* set ldo0 to HPM */
9389 rc = regulator_set_optimum_mode(ldo0, 100000);
9390 if (rc < 0)
9391 goto out;
9392 } else {
9393 /* set ldo0 to LPM */
9394 rc = regulator_set_optimum_mode(ldo0, 9000);
9395 if (rc < 0)
9396 goto out;
9397 }
9398
9399 return 0;
9400out:
9401 regulator_disable(ldo0);
9402 regulator_put(ldo0);
9403 ldo0 = NULL;
9404 return rc;
9405}
9406
9407static struct mipi_dsi_platform_data mipi_dsi_pdata = {
9408 .vsync_gpio = MDP_VSYNC_GPIO,
9409 .dsi_power_save = mipi_dsi_panel_power,
9410};
9411
9412#ifdef CONFIG_FB_MSM_TVOUT
9413static struct regulator *reg_8058_l13;
9414
9415static int atv_dac_power(int on)
9416{
9417 int rc = 0;
9418 #define _GET_REGULATOR(var, name) do { \
9419 var = regulator_get(NULL, name); \
9420 if (IS_ERR(var)) { \
9421 pr_info("'%s' regulator not found, rc=%ld\n", \
9422 name, IS_ERR(var)); \
9423 var = NULL; \
9424 return -ENODEV; \
9425 } \
9426 } while (0)
9427
9428 if (!reg_8058_l13)
9429 _GET_REGULATOR(reg_8058_l13, "8058_l13");
9430 #undef _GET_REGULATOR
9431
9432 if (on) {
9433 rc = regulator_set_voltage(reg_8058_l13, 2050000, 2050000);
9434 if (rc) {
9435 pr_info("%s: '%s' regulator set voltage failed,\
9436 rc=%d\n", __func__, "8058_l13", rc);
9437 return rc;
9438 }
9439
9440 rc = regulator_enable(reg_8058_l13);
9441 if (rc) {
9442 pr_err("%s: '%s' regulator enable failed,\
9443 rc=%d\n", __func__, "8058_l13", rc);
9444 return rc;
9445 }
9446 } else {
9447 rc = regulator_force_disable(reg_8058_l13);
9448 if (rc)
9449 pr_warning("%s: '%s' regulator disable failed, rc=%d\n",
9450 __func__, "8058_l13", rc);
9451 }
9452 return rc;
9453
9454}
9455#endif
9456
9457#ifdef CONFIG_FB_MSM_MIPI_DSI
9458int mdp_core_clk_rate_table[] = {
9459 85330000,
9460 85330000,
9461 160000000,
9462 200000000,
9463};
9464#else
9465int mdp_core_clk_rate_table[] = {
9466 59080000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07009467 85330000,
kuogee hsieh26791a92011-08-01 18:35:58 -07009468 128000000,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07009469 200000000,
9470};
9471#endif
9472
9473static struct msm_panel_common_pdata mdp_pdata = {
9474 .gpio = MDP_VSYNC_GPIO,
9475 .mdp_core_clk_rate = 59080000,
9476 .mdp_core_clk_table = mdp_core_clk_rate_table,
9477 .num_mdp_clk = ARRAY_SIZE(mdp_core_clk_rate_table),
9478#ifdef CONFIG_MSM_BUS_SCALING
9479 .mdp_bus_scale_table = &mdp_bus_scale_pdata,
9480#endif
9481 .mdp_rev = MDP_REV_41,
9482};
9483
9484#ifdef CONFIG_FB_MSM_TVOUT
9485
9486#ifdef CONFIG_MSM_BUS_SCALING
9487static struct msm_bus_vectors atv_bus_init_vectors[] = {
9488 /* For now, 0th array entry is reserved.
9489 * Please leave 0 as is and don't use it
9490 */
9491 {
9492 .src = MSM_BUS_MASTER_MDP_PORT0,
9493 .dst = MSM_BUS_SLAVE_SMI,
9494 .ab = 0,
9495 .ib = 0,
9496 },
9497 /* Master and slaves can be from different fabrics */
9498 {
9499 .src = MSM_BUS_MASTER_MDP_PORT0,
9500 .dst = MSM_BUS_SLAVE_EBI_CH0,
9501 .ab = 0,
9502 .ib = 0,
9503 },
9504};
9505static struct msm_bus_vectors atv_bus_def_vectors[] = {
9506 /* For now, 0th array entry is reserved.
9507 * Please leave 0 as is and don't use it
9508 */
9509 {
9510 .src = MSM_BUS_MASTER_MDP_PORT0,
9511 .dst = MSM_BUS_SLAVE_SMI,
9512 .ab = 236390400,
9513 .ib = 265939200,
9514 },
9515 /* Master and slaves can be from different fabrics */
9516 {
9517 .src = MSM_BUS_MASTER_MDP_PORT0,
9518 .dst = MSM_BUS_SLAVE_EBI_CH0,
9519 .ab = 236390400,
9520 .ib = 265939200,
9521 },
9522};
9523static struct msm_bus_paths atv_bus_scale_usecases[] = {
9524 {
9525 ARRAY_SIZE(atv_bus_init_vectors),
9526 atv_bus_init_vectors,
9527 },
9528 {
9529 ARRAY_SIZE(atv_bus_def_vectors),
9530 atv_bus_def_vectors,
9531 },
9532};
9533static struct msm_bus_scale_pdata atv_bus_scale_pdata = {
9534 atv_bus_scale_usecases,
9535 ARRAY_SIZE(atv_bus_scale_usecases),
9536 .name = "atv",
9537};
9538#endif
9539
9540static struct tvenc_platform_data atv_pdata = {
9541 .poll = 0,
9542 .pm_vid_en = atv_dac_power,
9543#ifdef CONFIG_MSM_BUS_SCALING
9544 .bus_scale_table = &atv_bus_scale_pdata,
9545#endif
9546};
9547#endif
9548
9549static void __init msm_fb_add_devices(void)
9550{
9551#ifdef CONFIG_FB_MSM_LCDC_DSUB
9552 mdp_pdata.mdp_core_clk_table = NULL;
9553 mdp_pdata.num_mdp_clk = 0;
9554 mdp_pdata.mdp_core_clk_rate = 200000000;
9555#endif
9556 if (machine_is_msm8x60_rumi3())
9557 msm_fb_register_device("mdp", NULL);
9558 else
9559 msm_fb_register_device("mdp", &mdp_pdata);
9560
9561 msm_fb_register_device("lcdc", &lcdc_pdata);
9562 msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
9563#ifdef CONFIG_MSM_BUS_SCALING
9564 msm_fb_register_device("dtv", &dtv_pdata);
9565#endif
9566#ifdef CONFIG_FB_MSM_TVOUT
9567 msm_fb_register_device("tvenc", &atv_pdata);
9568 msm_fb_register_device("tvout_device", NULL);
9569#endif
9570}
9571
9572#if (defined(CONFIG_MARIMBA_CORE)) && \
9573 (defined(CONFIG_MSM_BT_POWER) || defined(CONFIG_MSM_BT_POWER_MODULE))
9574
9575static const struct {
9576 char *name;
9577 int vmin;
9578 int vmax;
9579} bt_regs_info[] = {
9580 { "8058_s3", 1800000, 1800000 },
9581 { "8058_s2", 1300000, 1300000 },
9582 { "8058_l8", 2900000, 3050000 },
9583};
9584
9585static struct {
9586 bool enabled;
9587} bt_regs_status[] = {
9588 { false },
9589 { false },
9590 { false },
9591};
9592static struct regulator *bt_regs[ARRAY_SIZE(bt_regs_info)];
9593
9594static int bahama_bt(int on)
9595{
9596 int rc;
9597 int i;
9598 struct marimba config = { .mod_id = SLAVE_ID_BAHAMA};
9599
9600 struct bahama_variant_register {
9601 const size_t size;
9602 const struct bahama_config_register *set;
9603 };
9604
9605 const struct bahama_config_register *p;
9606
9607 u8 version;
9608
9609 const struct bahama_config_register v10_bt_on[] = {
9610 { 0xE9, 0x00, 0xFF },
9611 { 0xF4, 0x80, 0xFF },
9612 { 0xE4, 0x00, 0xFF },
9613 { 0xE5, 0x00, 0x0F },
9614#ifdef CONFIG_WLAN
9615 { 0xE6, 0x38, 0x7F },
9616 { 0xE7, 0x06, 0xFF },
9617#endif
9618 { 0xE9, 0x21, 0xFF },
9619 { 0x01, 0x0C, 0x1F },
9620 { 0x01, 0x08, 0x1F },
9621 };
9622
9623 const struct bahama_config_register v20_bt_on_fm_off[] = {
9624 { 0x11, 0x0C, 0xFF },
9625 { 0x13, 0x01, 0xFF },
9626 { 0xF4, 0x80, 0xFF },
9627 { 0xF0, 0x00, 0xFF },
9628 { 0xE9, 0x00, 0xFF },
9629#ifdef CONFIG_WLAN
9630 { 0x81, 0x00, 0x7F },
9631 { 0x82, 0x00, 0xFF },
9632 { 0xE6, 0x38, 0x7F },
9633 { 0xE7, 0x06, 0xFF },
9634#endif
9635 { 0xE9, 0x21, 0xFF },
9636 };
9637
9638 const struct bahama_config_register v20_bt_on_fm_on[] = {
9639 { 0x11, 0x0C, 0xFF },
9640 { 0x13, 0x01, 0xFF },
9641 { 0xF4, 0x86, 0xFF },
9642 { 0xF0, 0x06, 0xFF },
9643 { 0xE9, 0x00, 0xFF },
9644#ifdef CONFIG_WLAN
9645 { 0x81, 0x00, 0x7F },
9646 { 0x82, 0x00, 0xFF },
9647 { 0xE6, 0x38, 0x7F },
9648 { 0xE7, 0x06, 0xFF },
9649#endif
9650 { 0xE9, 0x21, 0xFF },
9651 };
9652
9653 const struct bahama_config_register v10_bt_off[] = {
9654 { 0xE9, 0x00, 0xFF },
9655 };
9656
9657 const struct bahama_config_register v20_bt_off_fm_off[] = {
9658 { 0xF4, 0x84, 0xFF },
9659 { 0xF0, 0x04, 0xFF },
9660 { 0xE9, 0x00, 0xFF }
9661 };
9662
9663 const struct bahama_config_register v20_bt_off_fm_on[] = {
9664 { 0xF4, 0x86, 0xFF },
9665 { 0xF0, 0x06, 0xFF },
9666 { 0xE9, 0x00, 0xFF }
9667 };
9668 const struct bahama_variant_register bt_bahama[2][3] = {
9669 {
9670 { ARRAY_SIZE(v10_bt_off), v10_bt_off },
9671 { ARRAY_SIZE(v20_bt_off_fm_off), v20_bt_off_fm_off },
9672 { ARRAY_SIZE(v20_bt_off_fm_on), v20_bt_off_fm_on }
9673 },
9674 {
9675 { ARRAY_SIZE(v10_bt_on), v10_bt_on },
9676 { ARRAY_SIZE(v20_bt_on_fm_off), v20_bt_on_fm_off },
9677 { ARRAY_SIZE(v20_bt_on_fm_on), v20_bt_on_fm_on }
9678 }
9679 };
9680
9681 u8 offset = 0; /* index into bahama configs */
9682
9683 on = on ? 1 : 0;
9684 version = read_bahama_ver();
9685
9686 if (version == VER_UNSUPPORTED) {
9687 dev_err(&msm_bt_power_device.dev,
9688 "%s: unsupported version\n",
9689 __func__);
9690 return -EIO;
9691 }
9692
9693 if (version == VER_2_0) {
9694 if (marimba_get_fm_status(&config))
9695 offset = 0x01;
9696 }
9697
9698 /* Voting off 1.3V S2 Regulator,BahamaV2 used in Normal mode */
9699 if (on && (version == VER_2_0)) {
9700 for (i = 0; i < ARRAY_SIZE(bt_regs_info); i++) {
9701 if ((!strcmp(bt_regs_info[i].name, "8058_s2"))
9702 && (bt_regs_status[i].enabled == true)) {
9703 if (regulator_disable(bt_regs[i])) {
9704 dev_err(&msm_bt_power_device.dev,
9705 "%s: regulator disable failed",
9706 __func__);
9707 }
9708 bt_regs_status[i].enabled = false;
9709 break;
9710 }
9711 }
9712 }
9713
9714 p = bt_bahama[on][version + offset].set;
9715
9716 dev_info(&msm_bt_power_device.dev,
9717 "%s: found version %d\n", __func__, version);
9718
9719 for (i = 0; i < bt_bahama[on][version + offset].size; i++) {
9720 u8 value = (p+i)->value;
9721 rc = marimba_write_bit_mask(&config,
9722 (p+i)->reg,
9723 &value,
9724 sizeof((p+i)->value),
9725 (p+i)->mask);
9726 if (rc < 0) {
9727 dev_err(&msm_bt_power_device.dev,
9728 "%s: reg %d write failed: %d\n",
9729 __func__, (p+i)->reg, rc);
9730 return rc;
9731 }
9732 dev_dbg(&msm_bt_power_device.dev,
9733 "%s: reg 0x%02x write value 0x%02x mask 0x%02x\n",
9734 __func__, (p+i)->reg,
9735 value, (p+i)->mask);
9736 }
9737 /* Update BT Status */
9738 if (on)
9739 marimba_set_bt_status(&config, true);
9740 else
9741 marimba_set_bt_status(&config, false);
9742
9743 return 0;
9744}
9745
9746static int bluetooth_use_regulators(int on)
9747{
9748 int i, recover = -1, rc = 0;
9749
9750 for (i = 0; i < ARRAY_SIZE(bt_regs_info); i++) {
9751 bt_regs[i] = on ? regulator_get(&msm_bt_power_device.dev,
9752 bt_regs_info[i].name) :
9753 (regulator_put(bt_regs[i]), NULL);
9754 if (IS_ERR(bt_regs[i])) {
9755 rc = PTR_ERR(bt_regs[i]);
9756 dev_err(&msm_bt_power_device.dev,
9757 "regulator %s get failed (%d)\n",
9758 bt_regs_info[i].name, rc);
9759 recover = i - 1;
9760 bt_regs[i] = NULL;
9761 break;
9762 }
9763
9764 if (!on)
9765 continue;
9766
9767 rc = regulator_set_voltage(bt_regs[i],
9768 bt_regs_info[i].vmin,
9769 bt_regs_info[i].vmax);
9770 if (rc < 0) {
9771 dev_err(&msm_bt_power_device.dev,
9772 "regulator %s voltage set (%d)\n",
9773 bt_regs_info[i].name, rc);
9774 recover = i;
9775 break;
9776 }
9777 }
9778
9779 if (on && (recover > -1))
9780 for (i = recover; i >= 0; i--) {
9781 regulator_put(bt_regs[i]);
9782 bt_regs[i] = NULL;
9783 }
9784
9785 return rc;
9786}
9787
9788static int bluetooth_switch_regulators(int on)
9789{
9790 int i, rc = 0;
9791
9792 for (i = 0; i < ARRAY_SIZE(bt_regs_info); i++) {
9793 if (on && (bt_regs_status[i].enabled == false)) {
9794 rc = regulator_enable(bt_regs[i]);
9795 if (rc < 0) {
9796 dev_err(&msm_bt_power_device.dev,
9797 "regulator %s %s failed (%d)\n",
9798 bt_regs_info[i].name,
9799 "enable", rc);
9800 if (i > 0) {
9801 while (--i) {
9802 regulator_disable(bt_regs[i]);
9803 bt_regs_status[i].enabled
9804 = false;
9805 }
9806 break;
9807 }
9808 }
9809 bt_regs_status[i].enabled = true;
9810 } else if (!on && (bt_regs_status[i].enabled == true)) {
9811 rc = regulator_disable(bt_regs[i]);
9812 if (rc < 0) {
9813 dev_err(&msm_bt_power_device.dev,
9814 "regulator %s %s failed (%d)\n",
9815 bt_regs_info[i].name,
9816 "disable", rc);
9817 break;
9818 }
9819 bt_regs_status[i].enabled = false;
9820 }
9821 }
9822 return rc;
9823}
9824
9825static struct msm_xo_voter *bt_clock;
9826
9827static int bluetooth_power(int on)
9828{
9829 int rc = 0;
9830 int id;
9831
9832 /* In case probe function fails, cur_connv_type would be -1 */
9833 id = adie_get_detected_connectivity_type();
9834 if (id != BAHAMA_ID) {
9835 pr_err("%s: unexpected adie connectivity type: %d\n",
9836 __func__, id);
9837 return -ENODEV;
9838 }
9839
9840 if (on) {
9841
9842 rc = bluetooth_use_regulators(1);
9843 if (rc < 0)
9844 goto out;
9845
9846 rc = bluetooth_switch_regulators(1);
9847
9848 if (rc < 0)
9849 goto fail_put;
9850
9851 bt_clock = msm_xo_get(MSM_XO_TCXO_D0, "bt_power");
9852
9853 if (IS_ERR(bt_clock)) {
9854 pr_err("Couldn't get TCXO_D0 voter\n");
9855 goto fail_switch;
9856 }
9857
9858 rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_ON);
9859
9860 if (rc < 0) {
9861 pr_err("Failed to vote for TCXO_DO ON\n");
9862 goto fail_vote;
9863 }
9864
9865 rc = bahama_bt(1);
9866
9867 if (rc < 0)
9868 goto fail_clock;
9869
9870 msleep(10);
9871
9872 rc = msm_xo_mode_vote(bt_clock, MSM_XO_MODE_PIN_CTRL);
9873
9874 if (rc < 0) {
9875 pr_err("Failed to vote for TCXO_DO pin control\n");
9876 goto fail_vote;
9877 }
9878 } else {
9879 /* check for initial RFKILL block (power off) */
9880 /* some RFKILL versions/configurations rfkill_register */
9881 /* calls here for an initial set_block */
9882 /* avoid calling i2c and regulator before unblock (on) */
9883 if (platform_get_drvdata(&msm_bt_power_device) == NULL) {
9884 dev_info(&msm_bt_power_device.dev,
9885 "%s: initialized OFF/blocked\n", __func__);
9886 goto out;
9887 }
9888
9889 bahama_bt(0);
9890
9891fail_clock:
9892 msm_xo_mode_vote(bt_clock, MSM_XO_MODE_OFF);
9893fail_vote:
9894 msm_xo_put(bt_clock);
9895fail_switch:
9896 bluetooth_switch_regulators(0);
9897fail_put:
9898 bluetooth_use_regulators(0);
9899 }
9900
9901out:
9902 if (rc < 0)
9903 on = 0;
9904 dev_info(&msm_bt_power_device.dev,
9905 "Bluetooth power switch: state %d result %d\n", on, rc);
9906
9907 return rc;
9908}
9909
9910#endif /*CONFIG_MARIMBA_CORE, CONFIG_MSM_BT_POWER, CONFIG_MSM_BT_POWER_MODULE*/
9911
9912static void __init msm8x60_cfg_smsc911x(void)
9913{
9914 smsc911x_resources[1].start =
9915 PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 6);
9916 smsc911x_resources[1].end =
9917 PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 6);
9918}
9919
9920#ifdef CONFIG_MSM_RPM
9921static struct msm_rpm_platform_data msm_rpm_data = {
9922 .reg_base_addrs = {
9923 [MSM_RPM_PAGE_STATUS] = MSM_RPM_BASE,
9924 [MSM_RPM_PAGE_CTRL] = MSM_RPM_BASE + 0x400,
9925 [MSM_RPM_PAGE_REQ] = MSM_RPM_BASE + 0x600,
9926 [MSM_RPM_PAGE_ACK] = MSM_RPM_BASE + 0xa00,
9927 },
9928
9929 .irq_ack = RPM_SCSS_CPU0_GP_HIGH_IRQ,
9930 .irq_err = RPM_SCSS_CPU0_GP_LOW_IRQ,
9931 .irq_vmpm = RPM_SCSS_CPU0_GP_MEDIUM_IRQ,
9932 .msm_apps_ipc_rpm_reg = MSM_GCC_BASE + 0x008,
9933 .msm_apps_ipc_rpm_val = 4,
9934};
9935#endif
9936
Laura Abbott5d2d1e62011-08-10 16:27:35 -07009937void msm_fusion_setup_pinctrl(void)
9938{
9939 struct msm_xo_voter *a1;
9940
9941 if (socinfo_get_platform_subtype() == 0x3) {
9942 /*
9943 * Vote for the A1 clock to be in pin control mode before
9944 * the external images are loaded.
9945 */
9946 a1 = msm_xo_get(MSM_XO_TCXO_A1, "mdm");
9947 BUG_ON(!a1);
9948 msm_xo_mode_vote(a1, MSM_XO_MODE_PIN_CTRL);
9949 }
9950}
9951
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07009952struct msm_board_data {
9953 struct msm_gpiomux_configs *gpiomux_cfgs;
9954};
9955
9956static struct msm_board_data msm8x60_rumi3_board_data __initdata = {
9957 .gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
9958};
9959
9960static struct msm_board_data msm8x60_sim_board_data __initdata = {
9961 .gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
9962};
9963
9964static struct msm_board_data msm8x60_surf_board_data __initdata = {
9965 .gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
9966};
9967
9968static struct msm_board_data msm8x60_ffa_board_data __initdata = {
9969 .gpiomux_cfgs = msm8x60_surf_ffa_gpiomux_cfgs,
9970};
9971
9972static struct msm_board_data msm8x60_fluid_board_data __initdata = {
9973 .gpiomux_cfgs = msm8x60_fluid_gpiomux_cfgs,
9974};
9975
9976static struct msm_board_data msm8x60_charm_surf_board_data __initdata = {
9977 .gpiomux_cfgs = msm8x60_charm_gpiomux_cfgs,
9978};
9979
9980static struct msm_board_data msm8x60_charm_ffa_board_data __initdata = {
9981 .gpiomux_cfgs = msm8x60_charm_gpiomux_cfgs,
9982};
9983
Zhang Chang Kenef05b172011-07-27 15:28:13 -04009984static struct msm_board_data msm8x60_dragon_board_data __initdata = {
9985 .gpiomux_cfgs = msm8x60_dragon_gpiomux_cfgs,
9986};
9987
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07009988static void __init msm8x60_init(struct msm_board_data *board_data)
9989{
9990 uint32_t soc_platform_version;
9991
9992 /*
9993 * Initialize RPM first as other drivers and devices may need
9994 * it for their initialization.
9995 */
9996#ifdef CONFIG_MSM_RPM
9997 BUG_ON(msm_rpm_init(&msm_rpm_data));
9998#endif
9999 BUG_ON(msm_rpmrs_levels_init(msm_rpmrs_levels,
10000 ARRAY_SIZE(msm_rpmrs_levels)));
10001 if (msm_xo_init())
10002 pr_err("Failed to initialize XO votes\n");
10003
10004 if (socinfo_init() < 0)
10005 printk(KERN_ERR "%s: socinfo_init() failed!\n",
10006 __func__);
10007 msm8x60_check_2d_hardware();
10008
10009 /* Change SPM handling of core 1 if PMM 8160 is present. */
10010 soc_platform_version = socinfo_get_platform_version();
10011 if (SOCINFO_VERSION_MAJOR(soc_platform_version) == 1 &&
10012 SOCINFO_VERSION_MINOR(soc_platform_version) >= 2) {
10013 struct msm_spm_platform_data *spm_data;
10014
10015 spm_data = &msm_spm_data_v1[1];
10016 spm_data->reg_init_values[MSM_SPM_REG_SAW_CFG] &= ~0x0F00UL;
10017 spm_data->reg_init_values[MSM_SPM_REG_SAW_CFG] |= 0x0100UL;
10018
10019 spm_data = &msm_spm_data[1];
10020 spm_data->reg_init_values[MSM_SPM_REG_SAW_CFG] &= ~0x0F00UL;
10021 spm_data->reg_init_values[MSM_SPM_REG_SAW_CFG] |= 0x0100UL;
10022 }
10023
10024 /*
10025 * Initialize SPM before acpuclock as the latter calls into SPM
10026 * driver to set ACPU voltages.
10027 */
10028 if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1)
10029 msm_spm_init(msm_spm_data, ARRAY_SIZE(msm_spm_data));
10030 else
10031 msm_spm_init(msm_spm_data_v1, ARRAY_SIZE(msm_spm_data_v1));
10032
10033 /*
10034 * Set regulators 8901_l4 and 8901_l6 to be always on in HPM for SURF
10035 * devices so that the RPM doesn't drop into a low power mode that an
10036 * un-reworked SURF cannot resume from.
10037 */
10038 if (machine_is_msm8x60_surf()) {
10039 rpm_vreg_init_pdata[RPM_VREG_ID_PM8901_L4]
10040 .init_data.constraints.always_on = 1;
10041 rpm_vreg_init_pdata[RPM_VREG_ID_PM8901_L6]
10042 .init_data.constraints.always_on = 1;
10043 }
10044
10045 /*
10046 * Disable regulator info printing so that regulator registration
10047 * messages do not enter the kmsg log.
10048 */
10049 regulator_suppress_info_printing();
10050
10051 /* Initialize regulators needed for clock_init. */
10052 platform_add_devices(early_regulators, ARRAY_SIZE(early_regulators));
10053
Stephen Boydbb600ae2011-08-02 20:11:40 -070010054 msm_clock_init(&msm8x60_clock_init_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010055
10056 /* Buses need to be initialized before early-device registration
10057 * to get the platform data for fabrics.
10058 */
10059 msm8x60_init_buses();
10060 platform_add_devices(early_devices, ARRAY_SIZE(early_devices));
10061 /* CPU frequency control is not supported on simulated targets. */
10062 if (!machine_is_msm8x60_rumi3() && !machine_is_msm8x60_sim())
Matt Wagantall6d9ebee2011-08-26 12:15:24 -070010063 acpuclk_init(&msm8x60_acpuclk_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010064
10065 /* No EBI2 on 8660 charm targets */
10066 if (!machine_is_msm8x60_fusion() && !machine_is_msm8x60_fusn_ffa())
10067 msm8x60_init_ebi2();
10068 msm8x60_init_tlmm();
10069 msm8x60_init_gpiomux(board_data->gpiomux_cfgs);
10070 msm8x60_init_uart12dm();
10071 msm8x60_init_mmc();
10072
10073#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
10074 msm8x60_init_pm8058_othc();
10075#endif
10076
10077 if (machine_is_msm8x60_fluid()) {
10078 pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
10079 platform_data = &fluid_keypad_data;
10080 pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
10081 = sizeof(fluid_keypad_data);
Zhang Chang Ken683be172011-08-10 17:45:34 -040010082 } else if (machine_is_msm8x60_dragon()) {
10083 pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
10084 platform_data = &dragon_keypad_data;
10085 pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
10086 = sizeof(dragon_keypad_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010087 } else {
10088 pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
10089 platform_data = &ffa_keypad_data;
10090 pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
10091 = sizeof(ffa_keypad_data);
10092
10093 }
10094
10095 /* Disable END_CALL simulation function of powerkey on fluid */
10096 if (machine_is_msm8x60_fluid()) {
10097 pwrkey_pdata.pwrkey_time_ms = 0;
10098 }
10099
Jilai Wang53d27a82011-07-13 14:32:58 -040010100 /* Specify reset pin for OV9726 */
10101 if (machine_is_msm8x60_dragon()) {
10102 msm_camera_sensor_ov9726_data.sensor_reset = 62;
10103 ov9726_sensor_8660_info.mount_angle = 270;
10104 }
10105
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010106 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
10107 machine_is_msm8x60_fluid() || machine_is_msm8x60_fusion() ||
Zhang Chang Ken6baadf02011-08-05 09:48:15 -040010108 machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_dragon()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010109 msm8x60_cfg_smsc911x();
10110 if (SOCINFO_VERSION_MAJOR(socinfo_get_version()) != 1)
10111 platform_add_devices(msm_footswitch_devices,
10112 msm_num_footswitch_devices);
10113 platform_add_devices(surf_devices,
10114 ARRAY_SIZE(surf_devices));
10115
10116#ifdef CONFIG_MSM_DSPS
10117 if (machine_is_msm8x60_fluid()) {
10118 platform_device_unregister(&msm_gsbi12_qup_i2c_device);
10119 msm8x60_init_dsps();
10120 }
10121#endif
10122
10123#ifdef CONFIG_USB_EHCI_MSM_72K
10124 /*
10125 * Drive MPP2 pin HIGH for PHY to generate ID interrupts on 8660
10126 * fluid
10127 */
10128 if (machine_is_msm8x60_fluid()) {
10129 pm8901_mpp_config_digital_out(1,
10130 PM8901_MPP_DIG_LEVEL_L5, 1);
10131 }
10132 msm_add_host(0, &msm_usb_host_pdata);
10133#endif
10134 } else {
10135 msm8x60_configure_smc91x();
10136 platform_add_devices(rumi_sim_devices,
10137 ARRAY_SIZE(rumi_sim_devices));
10138 }
10139#if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
Zhang Chang Ken6baadf02011-08-05 09:48:15 -040010140 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
10141 machine_is_msm8x60_dragon())
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010142 msm8x60_cfg_isp1763();
10143#endif
10144#ifdef CONFIG_BATTERY_MSM8X60
10145 if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
Zhang Chang Ken6baadf02011-08-05 09:48:15 -040010146 machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010147 machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_fluid())
10148 platform_device_register(&msm_charger_device);
10149#endif
10150
10151 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
10152 platform_add_devices(charm_devices, ARRAY_SIZE(charm_devices));
10153
Terence Hampson90508a92011-08-09 10:40:08 -040010154 if (machine_is_msm8x60_dragon()) {
10155 pm8058_charger_sub_dev.platform_data
10156 = &pmic8058_charger_dragon;
10157 pm8058_charger_sub_dev.pdata_size
10158 = sizeof(pmic8058_charger_dragon);
10159 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010160 if (!machine_is_msm8x60_fluid())
10161 pm8058_platform_data.charger_sub_device
10162 = &pm8058_charger_sub_dev;
10163
10164#if defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
10165 if (machine_is_msm8x60_fluid())
10166 platform_device_register(&msm_gsbi10_qup_spi_device);
10167 else
10168 platform_device_register(&msm_gsbi1_qup_spi_device);
10169#endif
10170
10171#if defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C) || \
10172 defined(CONFIG_TOUCHSCREEN_CYTTSP_I2C_MODULE)
10173 if (machine_is_msm8x60_fluid())
10174 cyttsp_set_params();
10175#endif
10176 if (!machine_is_msm8x60_sim())
10177 msm_fb_add_devices();
10178 fixup_i2c_configs();
10179 register_i2c_devices();
10180
Terence Hampson1c73fef2011-07-19 17:10:49 -040010181 if (machine_is_msm8x60_dragon())
10182 smsc911x_config.reset_gpio
10183 = GPIO_ETHERNET_RESET_N_DRAGON;
10184
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010185 platform_device_register(&smsc911x_device);
10186
10187#if (defined(CONFIG_SPI_QUP)) && \
10188 (defined(CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT) || \
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -040010189 defined(CONFIG_FB_MSM_LCDC_AUO_WVGA) || \
10190 defined(CONFIG_FB_MSM_LCDC_NT35582_WVGA))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010191
10192 if (machine_is_msm8x60_fluid()) {
10193#ifdef CONFIG_FB_MSM_LCDC_SAMSUNG_OLED_PT
10194 if (SOCINFO_VERSION_MAJOR(soc_platform_version) < 3) {
10195 spi_register_board_info(lcdc_samsung_spi_board_info,
10196 ARRAY_SIZE(lcdc_samsung_spi_board_info));
10197 } else
10198#endif
10199 {
10200#ifdef CONFIG_FB_MSM_LCDC_AUO_WVGA
10201 spi_register_board_info(lcdc_auo_spi_board_info,
10202 ARRAY_SIZE(lcdc_auo_spi_board_info));
10203#endif
10204 }
Zhang Chang Ken3a8b8512011-08-04 18:41:39 -040010205#ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
10206 } else if (machine_is_msm8x60_dragon()) {
10207 spi_register_board_info(lcdc_nt35582_spi_board_info,
10208 ARRAY_SIZE(lcdc_nt35582_spi_board_info));
10209#endif
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010210 }
10211#endif
10212
10213 msm_pm_set_platform_data(msm_pm_data, ARRAY_SIZE(msm_pm_data));
10214 msm_pm_set_rpm_wakeup_irq(RPM_SCSS_CPU0_WAKE_UP_IRQ);
10215 msm_cpuidle_set_states(msm_cstates, ARRAY_SIZE(msm_cstates),
10216 msm_pm_data);
10217
10218#ifdef CONFIG_SENSORS_MSM_ADC
10219 if (machine_is_msm8x60_fluid()) {
10220 msm_adc_pdata.dev_names = msm_adc_fluid_device_names;
10221 msm_adc_pdata.num_adc = ARRAY_SIZE(msm_adc_fluid_device_names);
10222 if (SOCINFO_VERSION_MAJOR(soc_platform_version) < 3)
10223 msm_adc_pdata.gpio_config = APROC_CONFIG;
10224 else
10225 msm_adc_pdata.gpio_config = MPROC_CONFIG;
10226 }
10227 msm_adc_pdata.target_hw = MSM_8x60;
10228#endif
10229#ifdef CONFIG_MSM8X60_AUDIO
10230 msm_snddev_init();
10231#endif
10232#if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
10233 if (machine_is_msm8x60_fluid())
10234 platform_device_register(&fluid_leds_gpio);
10235 else
10236 platform_device_register(&gpio_leds);
10237#endif
10238
10239 /* configure pmic leds */
10240 if (machine_is_msm8x60_fluid()) {
10241 pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
10242 platform_data = &pm8058_fluid_flash_leds_data;
10243 pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
10244 = sizeof(pm8058_fluid_flash_leds_data);
Terence Hampsonc0b6dfb2011-07-15 11:07:17 -040010245 } else if (machine_is_msm8x60_dragon()) {
10246 pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
10247 platform_data = &pm8058_dragon_leds_data;
10248 pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
10249 = sizeof(pm8058_dragon_leds_data);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010250 } else {
10251 pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
10252 platform_data = &pm8058_flash_leds_data;
10253 pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
10254 = sizeof(pm8058_flash_leds_data);
10255 }
10256
Zhang Chang Ken6baadf02011-08-05 09:48:15 -040010257 if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa() ||
10258 machine_is_msm8x60_dragon()) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010259 pm8058_platform_data.sub_devices[PM8058_SUBDEV_VIB].
10260 platform_data = &pmic_vib_pdata;
10261 pm8058_platform_data.sub_devices[PM8058_SUBDEV_VIB].
10262 pdata_size = sizeof(pmic_vib_pdata);
10263 }
10264
10265 msm8x60_multi_sdio_init();
Laura Abbott5d2d1e62011-08-10 16:27:35 -070010266
10267 if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
10268 msm_fusion_setup_pinctrl();
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010269}
10270
10271static void __init msm8x60_rumi3_init(void)
10272{
10273 msm8x60_init(&msm8x60_rumi3_board_data);
10274}
10275
10276static void __init msm8x60_sim_init(void)
10277{
10278 msm8x60_init(&msm8x60_sim_board_data);
10279}
10280
10281static void __init msm8x60_surf_init(void)
10282{
10283 msm8x60_init(&msm8x60_surf_board_data);
10284}
10285
10286static void __init msm8x60_ffa_init(void)
10287{
10288 msm8x60_init(&msm8x60_ffa_board_data);
10289}
10290
10291static void __init msm8x60_fluid_init(void)
10292{
10293 msm8x60_init(&msm8x60_fluid_board_data);
10294}
10295
10296static void __init msm8x60_charm_surf_init(void)
10297{
10298 msm8x60_init(&msm8x60_charm_surf_board_data);
10299}
10300
10301static void __init msm8x60_charm_ffa_init(void)
10302{
10303 msm8x60_init(&msm8x60_charm_ffa_board_data);
10304}
10305
10306static void __init msm8x60_charm_init_early(void)
10307{
10308 msm8x60_allocate_memory_regions();
Steve Mucklea55df6e2010-01-07 12:43:24 -080010309}
10310
Zhang Chang Kenef05b172011-07-27 15:28:13 -040010311static void __init msm8x60_dragon_init(void)
10312{
10313 msm8x60_init(&msm8x60_dragon_board_data);
10314}
10315
Steve Mucklea55df6e2010-01-07 12:43:24 -080010316MACHINE_START(MSM8X60_RUMI3, "QCT MSM8X60 RUMI3")
10317 .map_io = msm8x60_map_io,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010318 .reserve = msm8x60_reserve,
Steve Mucklea55df6e2010-01-07 12:43:24 -080010319 .init_irq = msm8x60_init_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010320 .init_machine = msm8x60_rumi3_init,
Steve Mucklea55df6e2010-01-07 12:43:24 -080010321 .timer = &msm_timer,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010322 .init_early = msm8x60_charm_init_early,
Steve Muckle49b76f72010-03-19 17:00:08 -070010323MACHINE_END
Steve Muckle57bbf1c2010-01-07 12:51:10 -080010324
10325MACHINE_START(MSM8X60_SIM, "QCT MSM8X60 SIMULATOR")
10326 .map_io = msm8x60_map_io,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010327 .reserve = msm8x60_reserve,
Steve Muckle57bbf1c2010-01-07 12:51:10 -080010328 .init_irq = msm8x60_init_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010329 .init_machine = msm8x60_sim_init,
Steve Muckle57bbf1c2010-01-07 12:51:10 -080010330 .timer = &msm_timer,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010331 .init_early = msm8x60_charm_init_early,
10332MACHINE_END
10333
10334MACHINE_START(MSM8X60_SURF, "QCT MSM8X60 SURF")
10335 .map_io = msm8x60_map_io,
10336 .reserve = msm8x60_reserve,
10337 .init_irq = msm8x60_init_irq,
10338 .init_machine = msm8x60_surf_init,
10339 .timer = &msm_timer,
10340 .init_early = msm8x60_charm_init_early,
Steve Muckle57bbf1c2010-01-07 12:51:10 -080010341MACHINE_END
Gregory Bean69b7f6f2010-04-04 22:29:02 -070010342
10343MACHINE_START(MSM8X60_FFA, "QCT MSM8X60 FFA")
10344 .map_io = msm8x60_map_io,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010345 .reserve = msm8x60_reserve,
Gregory Bean69b7f6f2010-04-04 22:29:02 -070010346 .init_irq = msm8x60_init_irq,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010347 .init_machine = msm8x60_ffa_init,
Gregory Bean69b7f6f2010-04-04 22:29:02 -070010348 .timer = &msm_timer,
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070010349 .init_early = msm8x60_charm_init_early,
10350MACHINE_END
10351
10352MACHINE_START(MSM8X60_FLUID, "QCT MSM8X60 FLUID")
10353 .map_io = msm8x60_map_io,
10354 .reserve = msm8x60_reserve,
10355 .init_irq = msm8x60_init_irq,
10356 .init_machine = msm8x60_fluid_init,
10357 .timer = &msm_timer,
10358 .init_early = msm8x60_charm_init_early,
10359MACHINE_END
10360
10361MACHINE_START(MSM8X60_FUSION, "QCT MSM8X60 FUSION SURF")
10362 .map_io = msm8x60_map_io,
10363 .reserve = msm8x60_reserve,
10364 .init_irq = msm8x60_init_irq,
10365 .init_machine = msm8x60_charm_surf_init,
10366 .timer = &msm_timer,
10367 .init_early = msm8x60_charm_init_early,
10368MACHINE_END
10369
10370MACHINE_START(MSM8X60_FUSN_FFA, "QCT MSM8X60 FUSION FFA")
10371 .map_io = msm8x60_map_io,
10372 .reserve = msm8x60_reserve,
10373 .init_irq = msm8x60_init_irq,
10374 .init_machine = msm8x60_charm_ffa_init,
10375 .timer = &msm_timer,
10376 .init_early = msm8x60_charm_init_early,
Gregory Bean69b7f6f2010-04-04 22:29:02 -070010377MACHINE_END
Zhang Chang Kenef05b172011-07-27 15:28:13 -040010378
10379MACHINE_START(MSM8X60_DRAGON, "QCT MSM8X60 DRAGON")
10380 .map_io = msm8x60_map_io,
10381 .reserve = msm8x60_reserve,
10382 .init_irq = msm8x60_init_irq,
10383 .init_machine = msm8x60_dragon_init,
10384 .timer = &msm_timer,
10385 .init_early = msm8x60_charm_init_early,
10386MACHINE_END