blob: 02dfc5eec8efbb8013cfdec77b72676c2e5aa900 [file] [log] [blame]
Jay Chokshie8741282012-01-25 15:22:55 -08001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -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 *
12 */
13
14#include <linux/init.h>
15#include <linux/ioport.h>
16#include <linux/platform_device.h>
17#include <linux/bootmem.h>
Jay Chokshie8741282012-01-25 15:22:55 -080018#include <linux/mfd/pm8xxx/pm8921.h>
19#include <linux/leds.h>
20#include <linux/leds-pm8xxx.h>
Jay Chokshif3a9ea82012-01-12 16:34:43 -080021#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -080022#include <asm/mach-types.h>
23#include <asm/mach/mmc.h>
24#include <mach/msm_bus_board.h>
25#include <mach/board.h>
26#include <mach/gpio.h>
27#include <mach/gpiomux.h>
Jay Chokshie8741282012-01-25 15:22:55 -080028#include <mach/restart.h>
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -080029#include "devices.h"
30#include "board-8064.h"
31
Jay Chokshie8741282012-01-25 15:22:55 -080032struct pm8xxx_gpio_init {
33 unsigned gpio;
34 struct pm_gpio config;
35};
36
37struct pm8xxx_mpp_init {
38 unsigned mpp;
39 struct pm8xxx_mpp_config_data config;
40};
41
42#define PM8921_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
43 _func, _inv, _disable) \
44{ \
45 .gpio = PM8921_GPIO_PM_TO_SYS(_gpio), \
46 .config = { \
47 .direction = _dir, \
48 .output_buffer = _buf, \
49 .output_value = _val, \
50 .pull = _pull, \
51 .vin_sel = _vin, \
52 .out_strength = _out_strength, \
53 .function = _func, \
54 .inv_int_pol = _inv, \
55 .disable_pin = _disable, \
56 } \
57}
58
59#define PM8921_MPP_INIT(_mpp, _type, _level, _control) \
60{ \
61 .mpp = PM8921_MPP_PM_TO_SYS(_mpp), \
62 .config = { \
63 .type = PM8XXX_MPP_TYPE_##_type, \
64 .level = _level, \
65 .control = PM8XXX_MPP_##_control, \
66 } \
67}
68
69#define PM8821_MPP_INIT(_mpp, _type, _level, _control) \
70{ \
71 .mpp = PM8821_MPP_PM_TO_SYS(_mpp), \
72 .config = { \
73 .type = PM8XXX_MPP_TYPE_##_type, \
74 .level = _level, \
75 .control = PM8XXX_MPP_##_control, \
76 } \
77}
78
79#define PM8921_GPIO_DISABLE(_gpio) \
80 PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
81 0, 0, 0, 1)
82
83#define PM8921_GPIO_OUTPUT(_gpio, _val, _strength) \
84 PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
85 PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
86 PM_GPIO_STRENGTH_##_strength, \
87 PM_GPIO_FUNC_NORMAL, 0, 0)
88
Jay Chokshi1de4f9d2012-02-07 16:11:31 -080089#define PM8921_GPIO_OUTPUT_BUFCONF(_gpio, _val, _strength, _bufconf) \
90 PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT,\
91 PM_GPIO_OUT_BUF_##_bufconf, _val, \
92 PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
93 PM_GPIO_STRENGTH_##_strength, \
94 PM_GPIO_FUNC_NORMAL, 0, 0)
95
Jay Chokshie8741282012-01-25 15:22:55 -080096#define PM8921_GPIO_INPUT(_gpio, _pull) \
97 PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
98 _pull, PM_GPIO_VIN_S4, \
99 PM_GPIO_STRENGTH_NO, \
100 PM_GPIO_FUNC_NORMAL, 0, 0)
101
102#define PM8921_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
103 PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
104 PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
105 PM_GPIO_STRENGTH_HIGH, \
106 _func, 0, 0)
107
108#define PM8921_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
109 PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
110 PM_GPIO_PULL_NO, _vin, \
111 PM_GPIO_STRENGTH_HIGH, \
112 PM_GPIO_FUNC_NORMAL, 0, 0)
113
114/* Initial PM8921 GPIO configurations */
115static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
David Collins390fc332012-02-07 14:38:16 -0800116 PM8921_GPIO_OUTPUT(23, 0, HIGH), /* touchscreen power FET */
Jay Chokshi1de4f9d2012-02-07 16:11:31 -0800117 PM8921_GPIO_OUTPUT_BUFCONF(25, 0, LOW, CMOS), /* DISP_RESET_N */
118 PM8921_GPIO_OUTPUT_FUNC(26, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
119 PM8921_GPIO_OUTPUT_BUFCONF(36, 1, LOW, OPEN_DRAIN),
Jay Chokshie8741282012-01-25 15:22:55 -0800120};
121
122/* Initial PM8XXX MPP configurations */
123static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
Jay Chokshi1de4f9d2012-02-07 16:11:31 -0800124 PM8921_MPP_INIT(3, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
David Collinsf0d00732012-01-25 15:46:50 -0800125 /* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
Jay Chokshi1de4f9d2012-02-07 16:11:31 -0800126 PM8921_MPP_INIT(7, D_OUTPUT, PM8921_MPP_DIG_LEVEL_VPH, DOUT_CTRL_LOW),
127 PM8921_MPP_INIT(8, D_OUTPUT, PM8921_MPP_DIG_LEVEL_S4, DOUT_CTRL_LOW),
Jay Chokshie8741282012-01-25 15:22:55 -0800128};
129
130void __init apq8064_pm8xxx_gpio_mpp_init(void)
131{
132 int i, rc;
133
134 for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
135 rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
136 &pm8921_gpios[i].config);
137 if (rc) {
138 pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
139 break;
140 }
141 }
142
143 for (i = 0; i < ARRAY_SIZE(pm8xxx_mpps); i++) {
144 rc = pm8xxx_mpp_config(pm8xxx_mpps[i].mpp,
145 &pm8xxx_mpps[i].config);
146 if (rc) {
147 pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
148 break;
149 }
150 }
151}
152
153static struct pm8xxx_pwrkey_platform_data apq8064_pm8921_pwrkey_pdata = {
154 .pull_up = 1,
155 .kpd_trigger_delay_us = 15625,
156 .wakeup = 1,
157};
158
159static struct pm8xxx_misc_platform_data apq8064_pm8921_misc_pdata = {
160 .priority = 0,
161};
162
163#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
164#define PM8921_LC_LED_LOW_CURRENT 1 /* I = 1mA */
165#define PM8XXX_LED_PWM_PERIOD 1000
166#define PM8XXX_LED_PWM_DUTY_MS 20
167/**
168 * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
169 * driven using PWM feature.
170 */
171#define PM8XXX_PWM_CHANNEL_NONE -1
172
173static struct led_info pm8921_led_info[] = {
174 [0] = {
175 .name = "led:red",
176 .default_trigger = "ac-online",
177 },
178};
179
180static struct led_platform_data pm8921_led_core_pdata = {
181 .num_leds = ARRAY_SIZE(pm8921_led_info),
182 .leds = pm8921_led_info,
183};
184
185static int pm8921_led0_pwm_duty_pcts[56] = {
186 1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
187 40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
188 80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
189 92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
190 58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
191 14, 10, 6, 4, 1
192};
193
194static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
195 .duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
196 .num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
197 .duty_ms = PM8XXX_LED_PWM_DUTY_MS,
198 .start_idx = 0,
199};
200
201static struct pm8xxx_led_config pm8921_led_configs[] = {
202 [0] = {
203 .id = PM8XXX_ID_LED_0,
204 .mode = PM8XXX_LED_MODE_PWM2,
205 .max_current = PM8921_LC_LED_MAX_CURRENT,
206 .pwm_channel = 5,
207 .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
208 .pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
209 },
210};
211
212static struct pm8xxx_led_platform_data apq8064_pm8921_leds_pdata = {
213 .led_core = &pm8921_led_core_pdata,
214 .configs = pm8921_led_configs,
215 .num_configs = ARRAY_SIZE(pm8921_led_configs),
216};
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -0800217
Jay Chokshif3a9ea82012-01-12 16:34:43 -0800218static struct pm8xxx_adc_amux apq8064_pm8921_adc_channels_data[] = {
219 {"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
220 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
221 {"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
222 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
223 {"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
224 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
225 {"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
226 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
227 {"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
228 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
229 {"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
230 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
231 {"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
232 ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
233 {"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
234 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
235 {"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
236 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
237 {"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
238 ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
239 {"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
240 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
241 {"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
242 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
243 {"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
244 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
245 {"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
246 ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
247};
248
249static struct pm8xxx_adc_properties apq8064_pm8921_adc_data = {
250 .adc_vdd_reference = 1800, /* milli-voltage for this adc */
251 .bitresolution = 15,
252 .bipolar = 0,
253};
254
255static struct pm8xxx_adc_platform_data apq8064_pm8921_adc_pdata = {
256 .adc_channel = apq8064_pm8921_adc_channels_data,
257 .adc_num_board_channel = ARRAY_SIZE(apq8064_pm8921_adc_channels_data),
258 .adc_prop = &apq8064_pm8921_adc_data,
259 .adc_mpp_base = PM8921_MPP_PM_TO_SYS(1),
260};
261
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -0800262static struct pm8xxx_mpp_platform_data
263apq8064_pm8921_mpp_pdata __devinitdata = {
264 .mpp_base = PM8921_MPP_PM_TO_SYS(1),
265};
266
267static struct pm8xxx_gpio_platform_data
268apq8064_pm8921_gpio_pdata __devinitdata = {
269 .gpio_base = PM8921_GPIO_PM_TO_SYS(1),
270};
271
272static struct pm8xxx_irq_platform_data
273apq8064_pm8921_irq_pdata __devinitdata = {
274 .irq_base = PM8921_IRQ_BASE,
275 .devirq = PM8921_USR_IRQ_N,
276 .irq_trigger_flag = IRQF_TRIGGER_HIGH,
277 .dev_id = 0,
278};
279
Ashay Jaiswal0b023dc2012-01-25 10:18:36 +0530280static struct pm8xxx_rtc_platform_data
281apq8064_pm8921_rtc_pdata = {
282 .rtc_write_enable = false,
283 .rtc_alarm_powerup = false,
284};
285
Jay Chokshi42fe9f02012-02-01 20:52:08 -0800286static int apq8064_pm8921_therm_mitigation[] = {
287 1100,
288 700,
289 600,
290 325,
291};
292
293#define MAX_VOLTAGE_MV 4200
294static struct pm8921_charger_platform_data
295apq8064_pm8921_chg_pdata __devinitdata = {
296 .safety_time = 180,
297 .update_time = 60000,
298 .max_voltage = MAX_VOLTAGE_MV,
299 .min_voltage = 3200,
300 .resume_voltage_delta = 100,
301 .term_current = 100,
302 .cool_temp = 10,
303 .warm_temp = 40,
304 .temp_check_period = 1,
305 .max_bat_chg_current = 1100,
306 .cool_bat_chg_current = 350,
307 .warm_bat_chg_current = 350,
308 .cool_bat_voltage = 4100,
309 .warm_bat_voltage = 4100,
310 .thermal_mitigation = apq8064_pm8921_therm_mitigation,
311 .thermal_levels = ARRAY_SIZE(apq8064_pm8921_therm_mitigation),
312};
313
314static struct pm8xxx_ccadc_platform_data
315apq8064_pm8xxx_ccadc_pdata = {
316 .r_sense = 10,
317};
318
319static struct pm8921_bms_platform_data
320apq8064_pm8921_bms_pdata __devinitdata = {
321 .r_sense = 10,
322 .i_test = 2500,
323 .v_failure = 3000,
324 .calib_delay_ms = 600000,
325 .max_voltage_uv = MAX_VOLTAGE_MV * 1000,
326};
327
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -0800328static struct pm8921_platform_data
329apq8064_pm8921_platform_data __devinitdata = {
330 .regulator_pdatas = msm8064_pm8921_regulator_pdata,
331 .irq_pdata = &apq8064_pm8921_irq_pdata,
332 .gpio_pdata = &apq8064_pm8921_gpio_pdata,
333 .mpp_pdata = &apq8064_pm8921_mpp_pdata,
Ashay Jaiswal0b023dc2012-01-25 10:18:36 +0530334 .rtc_pdata = &apq8064_pm8921_rtc_pdata,
Jay Chokshie8741282012-01-25 15:22:55 -0800335 .pwrkey_pdata = &apq8064_pm8921_pwrkey_pdata,
336 .misc_pdata = &apq8064_pm8921_misc_pdata,
337 .leds_pdata = &apq8064_pm8921_leds_pdata,
Jay Chokshif3a9ea82012-01-12 16:34:43 -0800338 .adc_pdata = &apq8064_pm8921_adc_pdata,
Jay Chokshi42fe9f02012-02-01 20:52:08 -0800339 .charger_pdata = &apq8064_pm8921_chg_pdata,
340 .bms_pdata = &apq8064_pm8921_bms_pdata,
341 .ccadc_pdata = &apq8064_pm8xxx_ccadc_pdata,
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -0800342};
343
344static struct pm8xxx_irq_platform_data
345apq8064_pm8821_irq_pdata __devinitdata = {
346 .irq_base = PM8821_IRQ_BASE,
Jay Chokshie8741282012-01-25 15:22:55 -0800347 .devirq = PM8821_SEC_IRQ_N,
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -0800348 .irq_trigger_flag = IRQF_TRIGGER_HIGH,
349 .dev_id = 1,
350};
351
352static struct pm8xxx_mpp_platform_data
353apq8064_pm8821_mpp_pdata __devinitdata = {
354 .mpp_base = PM8821_MPP_PM_TO_SYS(1),
355};
356
357static struct pm8821_platform_data
358apq8064_pm8821_platform_data __devinitdata = {
359 .irq_pdata = &apq8064_pm8821_irq_pdata,
360 .mpp_pdata = &apq8064_pm8821_mpp_pdata,
361};
362
363static struct msm_ssbi_platform_data apq8064_ssbi_pm8921_pdata __devinitdata = {
364 .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
365 .slave = {
366 .name = "pm8921-core",
367 .platform_data = &apq8064_pm8921_platform_data,
368 },
369};
370
371static struct msm_ssbi_platform_data apq8064_ssbi_pm8821_pdata __devinitdata = {
372 .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
373 .slave = {
374 .name = "pm8821-core",
375 .platform_data = &apq8064_pm8821_platform_data,
376 },
377};
378
379void __init apq8064_init_pmic(void)
380{
Jay Chokshie8741282012-01-25 15:22:55 -0800381 pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
382
Stepan Moskovchenkoc1074f02011-12-14 17:51:57 -0800383 apq8064_device_ssbi_pmic1.dev.platform_data =
384 &apq8064_ssbi_pm8921_pdata;
385 apq8064_device_ssbi_pmic2.dev.platform_data =
386 &apq8064_ssbi_pm8821_pdata;
387 apq8064_pm8921_platform_data.num_regulators =
388 msm8064_pm8921_regulator_pdata_len;
389
390 if (machine_is_apq8064_rumi3()) {
391 apq8064_pm8921_irq_pdata.devirq = 0;
392 apq8064_pm8821_irq_pdata.devirq = 0;
393 }
394}