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