blob: cfb2347a9352dcbf56409ebd960cb68cff2d0558 [file] [log] [blame]
Stepan Moskovchenko39236d72011-11-30 17:42:23 -08001/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/interrupt.h>
15#include <linux/mfd/pm8xxx/pm8921.h>
16#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
17#include <linux/leds.h>
18#include <linux/leds-pm8xxx.h>
19#include <linux/msm_ssbi.h>
20#include <asm/mach-types.h>
21#include <mach/msm_bus_board.h>
22#include <mach/restart.h>
23#include "devices.h"
Stepan Moskovchenko5a83dba2011-12-05 17:30:17 -080024#include "board-8930.h"
Stepan Moskovchenko39236d72011-11-30 17:42:23 -080025
26struct pm8xxx_gpio_init {
27 unsigned gpio;
28 struct pm_gpio config;
29};
30
31struct pm8xxx_mpp_init {
32 unsigned mpp;
33 struct pm8xxx_mpp_config_data config;
34};
35
36#define PM8XXX_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
37 _func, _inv, _disable) \
38{ \
39 .gpio = PM8921_GPIO_PM_TO_SYS(_gpio), \
40 .config = { \
41 .direction = _dir, \
42 .output_buffer = _buf, \
43 .output_value = _val, \
44 .pull = _pull, \
45 .vin_sel = _vin, \
46 .out_strength = _out_strength, \
47 .function = _func, \
48 .inv_int_pol = _inv, \
49 .disable_pin = _disable, \
50 } \
51}
52
53#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
54{ \
55 .mpp = PM8921_MPP_PM_TO_SYS(_mpp), \
56 .config = { \
57 .type = PM8XXX_MPP_TYPE_##_type, \
58 .level = _level, \
59 .control = PM8XXX_MPP_##_control, \
60 } \
61}
62
63#define PM8XXX_GPIO_DISABLE(_gpio) \
64 PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
65 0, 0, 0, 1)
66
67#define PM8XXX_GPIO_OUTPUT(_gpio, _val) \
68 PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
69 PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
70 PM_GPIO_STRENGTH_HIGH, \
71 PM_GPIO_FUNC_NORMAL, 0, 0)
72
73#define PM8XXX_GPIO_INPUT(_gpio, _pull) \
74 PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
75 _pull, PM_GPIO_VIN_S4, \
76 PM_GPIO_STRENGTH_NO, \
77 PM_GPIO_FUNC_NORMAL, 0, 0)
78
79#define PM8XXX_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
80 PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
81 PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
82 PM_GPIO_STRENGTH_HIGH, \
83 _func, 0, 0)
84
85#define PM8XXX_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
86 PM8XXX_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
87 PM_GPIO_PULL_NO, _vin, \
88 PM_GPIO_STRENGTH_HIGH, \
89 PM_GPIO_FUNC_NORMAL, 0, 0)
90
91/* Initial PM8921 GPIO configurations */
92static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
93 PM8XXX_GPIO_DISABLE(6), /* Disable unused */
94 PM8XXX_GPIO_DISABLE(7), /* Disable NFC */
95 PM8XXX_GPIO_INPUT(16, PM_GPIO_PULL_UP_30), /* SD_CARD_WP */
96 /* External regulator shared by display and touchscreen on LiQUID */
97 PM8XXX_GPIO_OUTPUT(17, 0), /* DISP 3.3 V Boost */
98 PM8XXX_GPIO_OUTPUT_VIN(21, 1, PM_GPIO_VIN_VPH), /* Backlight Enable */
99 PM8XXX_GPIO_DISABLE(22), /* Disable NFC */
100 PM8XXX_GPIO_OUTPUT_FUNC(24, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
101 PM8XXX_GPIO_INPUT(26, PM_GPIO_PULL_UP_30), /* SD_CARD_DET_N */
102 PM8XXX_GPIO_OUTPUT(43, PM_GPIO_PULL_UP_30), /* DISP_RESET_N */
103 PM8XXX_GPIO_OUTPUT(42, 0), /* USB 5V reg enable */
104};
105
106/* Initial PM8921 MPP configurations */
107static struct pm8xxx_mpp_init pm8921_mpps[] __initdata = {
108 /* External 5V regulator enable; shared by HDMI and USB_OTG switches. */
109 PM8XXX_MPP_INIT(7, D_INPUT, PM8921_MPP_DIG_LEVEL_VPH, DIN_TO_INT),
110 PM8XXX_MPP_INIT(PM8XXX_AMUX_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
111 DOUT_CTRL_LOW),
112};
113
114void __init msm8930_pm8921_gpio_mpp_init(void)
115{
116 int i, rc;
117
118 for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
119 rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
120 &pm8921_gpios[i].config);
121 if (rc) {
122 pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
123 break;
124 }
125 }
126
127 for (i = 0; i < ARRAY_SIZE(pm8921_mpps); i++) {
128 rc = pm8xxx_mpp_config(pm8921_mpps[i].mpp,
129 &pm8921_mpps[i].config);
130 if (rc) {
131 pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
132 break;
133 }
134 }
135}
136
137static struct pm8xxx_adc_amux pm8xxx_adc_channels_data[] = {
138 {"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
139 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
140 {"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
141 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
142 {"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
143 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
144 {"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
145 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
146 {"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
147 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
148 {"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
149 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
150 {"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
151 ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
152 {"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
153 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
154 {"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
155 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
156 {"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
157 ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
158 {"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
159 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
160 {"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
161 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
162 {"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
163 ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
164 {"pa_therm1", ADC_MPP_1_AMUX8, CHAN_PATH_SCALING1, AMUX_RSV1,
165 ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
166 {"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
167 ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
168 {"pa_therm0", ADC_MPP_1_AMUX3, CHAN_PATH_SCALING1, AMUX_RSV1,
169 ADC_DECIMATION_TYPE2, ADC_SCALE_PA_THERM},
170};
171
172static struct pm8xxx_adc_properties pm8xxx_adc_data = {
173 .adc_vdd_reference = 1800, /* milli-voltage for this adc */
174 .bitresolution = 15,
175 .bipolar = 0,
176};
177
178static struct pm8xxx_adc_platform_data pm8xxx_adc_pdata = {
179 .adc_channel = pm8xxx_adc_channels_data,
180 .adc_num_board_channel = ARRAY_SIZE(pm8xxx_adc_channels_data),
181 .adc_prop = &pm8xxx_adc_data,
182 .adc_mpp_base = PM8921_MPP_PM_TO_SYS(1),
183};
184
185
186static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata __devinitdata = {
187 .irq_base = PM8921_IRQ_BASE,
188 .devirq = MSM_GPIO_TO_INT(104),
189 .irq_trigger_flag = IRQF_TRIGGER_LOW,
190};
191
192static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata __devinitdata = {
193 .gpio_base = PM8921_GPIO_PM_TO_SYS(1),
194};
195
196static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata __devinitdata = {
197 .mpp_base = PM8921_MPP_PM_TO_SYS(1),
198};
199
200static struct pm8xxx_rtc_platform_data pm8xxx_rtc_pdata __devinitdata = {
201 .rtc_write_enable = false,
202 .rtc_alarm_powerup = false,
203};
204
205static struct pm8xxx_pwrkey_platform_data pm8xxx_pwrkey_pdata = {
206 .pull_up = 1,
207 .kpd_trigger_delay_us = 970,
208 .wakeup = 1,
209};
210
211/* Rotate lock key is not available so use F1 */
212#define KEY_ROTATE_LOCK KEY_F1
213
214static const unsigned int keymap_liquid[] = {
215 KEY(0, 0, KEY_VOLUMEUP),
216 KEY(0, 1, KEY_VOLUMEDOWN),
217 KEY(1, 3, KEY_ROTATE_LOCK),
218 KEY(1, 4, KEY_HOME),
219};
220
221static const unsigned int keymap[] = {
222 KEY(0, 0, KEY_VOLUMEUP),
223 KEY(0, 1, KEY_VOLUMEDOWN),
224 KEY(0, 2, KEY_CAMERA_SNAPSHOT),
225 KEY(0, 3, KEY_CAMERA_FOCUS),
226};
227
228static struct matrix_keymap_data keymap_data = {
229 .keymap_size = ARRAY_SIZE(keymap),
230 .keymap = keymap,
231};
232
233static struct pm8xxx_keypad_platform_data keypad_data = {
234 .input_name = "keypad_8960",
235 .input_phys_device = "keypad_8960/input0",
236 .num_rows = 1,
237 .num_cols = 5,
238 .rows_gpio_start = PM8921_GPIO_PM_TO_SYS(9),
239 .cols_gpio_start = PM8921_GPIO_PM_TO_SYS(1),
240 .debounce_ms = 15,
241 .scan_delay_ms = 32,
242 .row_hold_ns = 91500,
243 .wakeup = 1,
244 .keymap_data = &keymap_data,
245};
246
247static const unsigned int keymap_sim[] = {
248 KEY(0, 0, KEY_7),
249 KEY(0, 1, KEY_DOWN),
250 KEY(0, 2, KEY_UP),
251 KEY(0, 3, KEY_RIGHT),
252 KEY(0, 4, KEY_ENTER),
253 KEY(0, 5, KEY_L),
254 KEY(0, 6, KEY_BACK),
255 KEY(0, 7, KEY_M),
256
257 KEY(1, 0, KEY_LEFT),
258 KEY(1, 1, KEY_SEND),
259 KEY(1, 2, KEY_1),
260 KEY(1, 3, KEY_4),
261 KEY(1, 4, KEY_CLEAR),
262 KEY(1, 5, KEY_MSDOS),
263 KEY(1, 6, KEY_SPACE),
264 KEY(1, 7, KEY_COMMA),
265
266 KEY(2, 0, KEY_6),
267 KEY(2, 1, KEY_5),
268 KEY(2, 2, KEY_8),
269 KEY(2, 3, KEY_3),
270 KEY(2, 4, KEY_NUMERIC_STAR),
271 KEY(2, 5, KEY_UP),
272 KEY(2, 6, KEY_DOWN),
273 KEY(2, 7, KEY_LEFTSHIFT),
274
275 KEY(3, 0, KEY_9),
276 KEY(3, 1, KEY_NUMERIC_POUND),
277 KEY(3, 2, KEY_0),
278 KEY(3, 3, KEY_2),
279 KEY(3, 4, KEY_SLEEP),
280 KEY(3, 5, KEY_F1),
281 KEY(3, 6, KEY_F2),
282 KEY(3, 7, KEY_F3),
283
284 KEY(4, 0, KEY_BACK),
285 KEY(4, 1, KEY_HOME),
286 KEY(4, 2, KEY_MENU),
287 KEY(4, 3, KEY_VOLUMEUP),
288 KEY(4, 4, KEY_VOLUMEDOWN),
289 KEY(4, 5, KEY_F4),
290 KEY(4, 6, KEY_F5),
291 KEY(4, 7, KEY_F6),
292
293 KEY(5, 0, KEY_R),
294 KEY(5, 1, KEY_T),
295 KEY(5, 2, KEY_Y),
296 KEY(5, 3, KEY_LEFTALT),
297 KEY(5, 4, KEY_KPENTER),
298 KEY(5, 5, KEY_Q),
299 KEY(5, 6, KEY_W),
300 KEY(5, 7, KEY_E),
301
302 KEY(6, 0, KEY_F),
303 KEY(6, 1, KEY_G),
304 KEY(6, 2, KEY_H),
305 KEY(6, 3, KEY_CAPSLOCK),
306 KEY(6, 4, KEY_PAGEUP),
307 KEY(6, 5, KEY_A),
308 KEY(6, 6, KEY_S),
309 KEY(6, 7, KEY_D),
310
311 KEY(7, 0, KEY_V),
312 KEY(7, 1, KEY_B),
313 KEY(7, 2, KEY_N),
314 KEY(7, 3, KEY_MENU),
315 KEY(7, 4, KEY_PAGEDOWN),
316 KEY(7, 5, KEY_Z),
317 KEY(7, 6, KEY_X),
318 KEY(7, 7, KEY_C),
319
320 KEY(8, 0, KEY_P),
321 KEY(8, 1, KEY_J),
322 KEY(8, 2, KEY_K),
323 KEY(8, 3, KEY_INSERT),
324 KEY(8, 4, KEY_LINEFEED),
325 KEY(8, 5, KEY_U),
326 KEY(8, 6, KEY_I),
327 KEY(8, 7, KEY_O),
328
329 KEY(9, 0, KEY_4),
330 KEY(9, 1, KEY_5),
331 KEY(9, 2, KEY_6),
332 KEY(9, 3, KEY_7),
333 KEY(9, 4, KEY_8),
334 KEY(9, 5, KEY_1),
335 KEY(9, 6, KEY_2),
336 KEY(9, 7, KEY_3),
337
338 KEY(10, 0, KEY_F7),
339 KEY(10, 1, KEY_F8),
340 KEY(10, 2, KEY_F9),
341 KEY(10, 3, KEY_F10),
342 KEY(10, 4, KEY_FN),
343 KEY(10, 5, KEY_9),
344 KEY(10, 6, KEY_0),
345 KEY(10, 7, KEY_DOT),
346
347 KEY(11, 0, KEY_LEFTCTRL),
348 KEY(11, 1, KEY_F11),
349 KEY(11, 2, KEY_ENTER),
350 KEY(11, 3, KEY_SEARCH),
351 KEY(11, 4, KEY_DELETE),
352 KEY(11, 5, KEY_RIGHT),
353 KEY(11, 6, KEY_LEFT),
354 KEY(11, 7, KEY_RIGHTSHIFT),
355 KEY(0, 0, KEY_VOLUMEUP),
356 KEY(0, 1, KEY_VOLUMEDOWN),
357 KEY(0, 2, KEY_CAMERA_SNAPSHOT),
358 KEY(0, 3, KEY_CAMERA_FOCUS),
359};
360
361static int pm8921_therm_mitigation[] = {
362 1100,
363 700,
364 600,
365 325,
366};
367
368static struct pm8921_charger_platform_data pm8921_chg_pdata __devinitdata = {
369 .safety_time = 180,
370 .update_time = 60000,
371 .max_voltage = 4200,
372 .min_voltage = 3200,
373 .resume_voltage_delta = 100,
374 .term_current = 100,
375 .cool_temp = 10,
376 .warm_temp = 40,
377 .temp_check_period = 1,
378 .max_bat_chg_current = 1100,
379 .cool_bat_chg_current = 350,
380 .warm_bat_chg_current = 350,
381 .cool_bat_voltage = 4100,
382 .warm_bat_voltage = 4100,
383 .thermal_mitigation = pm8921_therm_mitigation,
384 .thermal_levels = ARRAY_SIZE(pm8921_therm_mitigation),
385};
386
387static struct pm8xxx_misc_platform_data pm8xxx_misc_pdata = {
388 .priority = 0,
389};
390
391static struct pm8921_bms_platform_data pm8921_bms_pdata __devinitdata = {
392 .r_sense = 10,
393 .i_test = 2500,
394 .v_failure = 3000,
395 .calib_delay_ms = 600000,
396};
397
398#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
399#define PM8XXX_LED_PWM_PERIOD 1000
400#define PM8XXX_LED_PWM_DUTY_MS 20
401/**
402 * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
403 * driven using PWM feature.
404 */
405#define PM8XXX_PWM_CHANNEL_NONE -1
406
407static struct led_info pm8921_led_info[] = {
408 [0] = {
409 .name = "led:battery_charging",
410 .default_trigger = "battery-charging",
411 },
412 [1] = {
413 .name = "led:battery_full",
414 .default_trigger = "battery-full",
415 },
416};
417
418static struct led_platform_data pm8921_led_core_pdata = {
419 .num_leds = ARRAY_SIZE(pm8921_led_info),
420 .leds = pm8921_led_info,
421};
422
423static int pm8921_led0_pwm_duty_pcts[56] = {
424 1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
425 40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
426 80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
427 92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
428 58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
429 14, 10, 6, 4, 1
430};
431
432static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
433 .duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
434 .num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
435 .duty_ms = PM8XXX_LED_PWM_DUTY_MS,
436 .start_idx = 0,
437};
438
439static struct pm8xxx_led_config pm8921_led_configs[] = {
440 [0] = {
441 .id = PM8XXX_ID_LED_0,
442 .mode = PM8XXX_LED_MODE_PWM2,
443 .max_current = PM8921_LC_LED_MAX_CURRENT,
444 .pwm_channel = 5,
445 .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
446 .pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
447 },
448 [1] = {
449 .id = PM8XXX_ID_LED_1,
450 .mode = PM8XXX_LED_MODE_PWM1,
451 .max_current = PM8921_LC_LED_MAX_CURRENT,
452 .pwm_channel = 4,
453 .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
454 },
455};
456
457static struct pm8xxx_led_platform_data pm8xxx_leds_pdata = {
458 .led_core = &pm8921_led_core_pdata,
459 .configs = pm8921_led_configs,
460 .num_configs = ARRAY_SIZE(pm8921_led_configs),
461};
462
463static struct pm8xxx_ccadc_platform_data pm8xxx_ccadc_pdata = {
464 .r_sense = 10,
465};
466
467static struct pm8921_platform_data pm8921_platform_data __devinitdata = {
468 .irq_pdata = &pm8xxx_irq_pdata,
469 .gpio_pdata = &pm8xxx_gpio_pdata,
470 .mpp_pdata = &pm8xxx_mpp_pdata,
471 .rtc_pdata = &pm8xxx_rtc_pdata,
472 .pwrkey_pdata = &pm8xxx_pwrkey_pdata,
473 .keypad_pdata = &keypad_data,
474 .misc_pdata = &pm8xxx_misc_pdata,
475 .regulator_pdatas = msm_pm8921_regulator_pdata,
476 .charger_pdata = &pm8921_chg_pdata,
477 .bms_pdata = &pm8921_bms_pdata,
478 .adc_pdata = &pm8xxx_adc_pdata,
479 .leds_pdata = &pm8xxx_leds_pdata,
480 .ccadc_pdata = &pm8xxx_ccadc_pdata,
481};
482
483static struct msm_ssbi_platform_data msm8960_ssbi_pm8921_pdata __devinitdata = {
484 .controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
485 .slave = {
486 .name = "pm8921-core",
487 .platform_data = &pm8921_platform_data,
488 },
489};
490
491void __init msm8930_init_pmic(void)
492{
493 pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
494 msm8960_device_ssbi_pm8921.dev.platform_data =
495 &msm8960_ssbi_pm8921_pdata;
496 pm8921_platform_data.num_regulators = msm_pm8921_regulator_pdata_len;
497
498 /* Simulator supports a QWERTY keypad */
499}