blob: ad35ef796fcca448d7271b31df6bda7191a483d6 [file]
/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
* Copyright (c) 2012, LGE Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
#include <linux/mfd/pm8xxx/pm8921.h>
#include <linux/leds.h>
#include <linux/leds-pm8xxx.h>
#include <linux/mfd/pm8xxx/pm8xxx-adc.h>
#include <linux/mfd/pm8xxx/pm8921-bms.h>
#include <linux/power/bq51051b_charger.h>
#include <linux/platform_data/battery_temp_ctrl.h>
#include <asm/mach-types.h>
#include <asm/mach/mmc.h>
#include <mach/msm_bus_board.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
#include <mach/restart.h>
#include <mach/board_lge.h>
#include "devices.h"
#include "board-mako.h"
#include "board-mako-pmic.h"
struct pm8xxx_gpio_init {
unsigned gpio;
struct pm_gpio config;
};
struct pm8xxx_mpp_init {
unsigned mpp;
struct pm8xxx_mpp_config_data config;
};
#define PM8921_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
_func, _inv, _disable) \
{ \
.gpio = PM8921_GPIO_PM_TO_SYS(_gpio), \
.config = { \
.direction = _dir, \
.output_buffer = _buf, \
.output_value = _val, \
.pull = _pull, \
.vin_sel = _vin, \
.out_strength = _out_strength, \
.function = _func, \
.inv_int_pol = _inv, \
.disable_pin = _disable, \
} \
}
#define PM8921_MPP_INIT(_mpp, _type, _level, _control) \
{ \
.mpp = PM8921_MPP_PM_TO_SYS(_mpp), \
.config = { \
.type = PM8XXX_MPP_TYPE_##_type, \
.level = _level, \
.control = PM8XXX_MPP_##_control, \
} \
}
#define PM8821_MPP_INIT(_mpp, _type, _level, _control) \
{ \
.mpp = PM8821_MPP_PM_TO_SYS(_mpp), \
.config = { \
.type = PM8XXX_MPP_TYPE_##_type, \
.level = _level, \
.control = PM8XXX_MPP_##_control, \
} \
}
#define PM8921_GPIO_DISABLE(_gpio) \
PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
0, 0, 0, 1)
#define PM8921_GPIO_OUTPUT(_gpio, _val, _strength) \
PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
PM_GPIO_STRENGTH_##_strength, \
PM_GPIO_FUNC_NORMAL, 0, 0)
#define PM8921_GPIO_OUTPUT_BUFCONF(_gpio, _val, _strength, _bufconf) \
PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT,\
PM_GPIO_OUT_BUF_##_bufconf, _val, \
PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
PM_GPIO_STRENGTH_##_strength, \
PM_GPIO_FUNC_NORMAL, 0, 0)
#define PM8921_GPIO_INPUT(_gpio, _pull) \
PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
_pull, PM_GPIO_VIN_S4, \
PM_GPIO_STRENGTH_NO, \
PM_GPIO_FUNC_NORMAL, 0, 0)
#define PM8921_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
PM_GPIO_STRENGTH_HIGH, \
_func, 0, 0)
#define PM8921_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
PM_GPIO_PULL_NO, _vin, \
PM_GPIO_STRENGTH_HIGH, \
PM_GPIO_FUNC_NORMAL, 0, 0)
/* Initial PM8921 GPIO configurations */
static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
PM8921_GPIO_INPUT(13, PM_GPIO_PULL_DN), /* EARJACK_DEBUGGER */
PM8921_GPIO_INPUT(14, PM_GPIO_PULL_DN), /* SLIMPORT_CBL_DET */
PM8921_GPIO_OUTPUT(15, 0, HIGH), /* ANX_P_DWN_CTL */
PM8921_GPIO_OUTPUT(16, 0, HIGH), /* ANX_AVDD33_EN */
PM8921_GPIO_OUTPUT(17, 0, HIGH), /* CAM_VCM_EN */
PM8921_GPIO_OUTPUT(19, 0, HIGH), /* AMP_EN_AMP */
PM8921_GPIO_OUTPUT(20, 0, HIGH), /* PMIC - FSA8008 EAR_MIC_BIAS_EN */
#ifdef CONFIG_WIRELESS_CHARGER
PM8921_GPIO_INPUT(25,PM_GPIO_PULL_UP_1P5_30), /* WLC ACTIVE_N */
PM8921_GPIO_OUTPUT(26, 0, HIGH), /* WLC CHG_STAT */
#endif
PM8921_GPIO_OUTPUT(31, 0, HIGH), /* PMIC - FSA8008_EAR_MIC_EN */
PM8921_GPIO_INPUT(32, PM_GPIO_PULL_UP_1P5), /* PMIC - FSA8008_EARPOL_DETECT */
PM8921_GPIO_OUTPUT(33, 0, HIGH), /* HAPTIC_EN */
PM8921_GPIO_OUTPUT(34, 0, HIGH), /* WCD_RESET_N */
};
void __init apq8064_pm8xxx_gpio_mpp_init(void)
{
int i, rc;
for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
&pm8921_gpios[i].config);
if (rc) {
pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
break;
}
}
}
static struct pm8xxx_pwrkey_platform_data apq8064_pm8921_pwrkey_pdata = {
.pull_up = 1,
.kpd_trigger_delay_us = 15625,
.wakeup = 1,
};
static struct pm8xxx_misc_platform_data apq8064_pm8921_misc_pdata = {
.priority = 0,
};
#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
#define PM8921_LC_LED_LOW_CURRENT 1 /* I = 1mA */
#define PM8XXX_LED_PWM_ADJUST_BRIGHTNESS_E 10 /* max duty percentage */
#define PM8XXX_LED_PWM_ADJUST_BRIGHTNESS 60 /* max duty percentage */
#define PM8XXX_LED_PWM_PERIOD 1000
#define PM8XXX_LED_PWM_DUTY_MS 50
#define PM8XXX_LED_PWM_DUTY_PCTS 16
#define PM8XXX_LED_PWM_START_IDX0 16
#define PM8XXX_LED_PWM_START_IDX1 32
#define PM8XXX_LED_PWM_START_IDX2 48
/**
* PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
* driven using PWM feature.
*/
#define PM8XXX_PWM_CHANNEL_NONE -1
static struct led_info pm8921_led_info[] = {
[0] = {
.name = "red",
},
[1] = {
.name = "green",
},
[2] = {
.name = "blue",
},
};
static struct led_platform_data pm8921_led_core_pdata = {
.num_leds = ARRAY_SIZE(pm8921_led_info),
.leds = pm8921_led_info,
};
static int pm8921_led0_pwm_duty_pcts[PM8XXX_LED_PWM_DUTY_PCTS] = {0,};
static int pm8921_led1_pwm_duty_pcts[PM8XXX_LED_PWM_DUTY_PCTS] = {0,};
static int pm8921_led2_pwm_duty_pcts[PM8XXX_LED_PWM_DUTY_PCTS] = {0,};
static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
.duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
.num_duty_pcts = PM8XXX_LED_PWM_DUTY_PCTS,
.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
.start_idx = PM8XXX_LED_PWM_START_IDX0,
};
static struct pm8xxx_pwm_duty_cycles pm8921_led1_pwm_duty_cycles = {
.duty_pcts = (int *)&pm8921_led1_pwm_duty_pcts,
.num_duty_pcts = PM8XXX_LED_PWM_DUTY_PCTS,
.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
.start_idx = PM8XXX_LED_PWM_START_IDX1,
};
static struct pm8xxx_pwm_duty_cycles pm8921_led2_pwm_duty_cycles = {
.duty_pcts = (int *)&pm8921_led2_pwm_duty_pcts,
.num_duty_pcts = PM8XXX_LED_PWM_DUTY_PCTS,
.duty_ms = PM8XXX_LED_PWM_DUTY_MS,
.start_idx = PM8XXX_LED_PWM_START_IDX2,
};
static struct pm8xxx_led_config pm8921_led_configs[] = {
[0] = {
.id = PM8XXX_ID_LED_0,
.mode = PM8XXX_LED_MODE_PWM3,
.max_current = PM8921_LC_LED_MAX_CURRENT,
.pwm_channel = 6,
.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
.pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
.pwm_adjust_brightness = PM8XXX_LED_PWM_ADJUST_BRIGHTNESS,
},
[1] = {
.id = PM8XXX_ID_LED_1,
.mode = PM8XXX_LED_MODE_PWM2,
.max_current = PM8921_LC_LED_MAX_CURRENT,
.pwm_channel = 5,
.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
.pwm_duty_cycles = &pm8921_led1_pwm_duty_cycles,
.pwm_adjust_brightness = PM8XXX_LED_PWM_ADJUST_BRIGHTNESS,
},
[2] = {
.id = PM8XXX_ID_LED_2,
.mode = PM8XXX_LED_MODE_PWM1,
.max_current = PM8921_LC_LED_MAX_CURRENT,
.pwm_channel = 4,
.pwm_period_us = PM8XXX_LED_PWM_PERIOD,
.pwm_duty_cycles = &pm8921_led2_pwm_duty_cycles,
.pwm_adjust_brightness = PM8XXX_LED_PWM_ADJUST_BRIGHTNESS,
},
};
static __init void mako_fixed_leds(void) {
if (lge_get_board_revno() <= HW_REV_E) {
int i = 0;
for (i = 0; i < ARRAY_SIZE(pm8921_led_configs); i++)
pm8921_led_configs[i].pwm_adjust_brightness =
PM8XXX_LED_PWM_ADJUST_BRIGHTNESS_E;
}
}
static struct pm8xxx_led_platform_data apq8064_pm8921_leds_pdata = {
.led_core = &pm8921_led_core_pdata,
.configs = pm8921_led_configs,
.num_configs = ARRAY_SIZE(pm8921_led_configs),
.use_pwm = 1,
};
static struct pm8xxx_adc_amux apq8064_pm8921_adc_channels_data[] = {
{"vcoin", CHANNEL_VCOIN, CHAN_PATH_SCALING2, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"vbat", CHANNEL_VBAT, CHAN_PATH_SCALING2, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"dcin", CHANNEL_DCIN, CHAN_PATH_SCALING4, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"ichg", CHANNEL_ICHG, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"vph_pwr", CHANNEL_VPH_PWR, CHAN_PATH_SCALING2, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"ibat", CHANNEL_IBAT, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"batt_therm", CHANNEL_BATT_THERM, CHAN_PATH_SCALING1, AMUX_RSV2,
ADC_DECIMATION_TYPE2, ADC_SCALE_BATT_THERM},
{"batt_id", CHANNEL_BATT_ID, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"usbin", CHANNEL_USBIN, CHAN_PATH_SCALING3, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"pmic_therm", CHANNEL_DIE_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_PMIC_THERM},
{"625mv", CHANNEL_625MV, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"125v", CHANNEL_125V, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"chg_temp", CHANNEL_CHG_TEMP, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
{"xo_therm", CHANNEL_MUXOFF, CHAN_PATH_SCALING1, AMUX_RSV0,
ADC_DECIMATION_TYPE2, ADC_SCALE_XOTHERM},
{"usb_id", ADC_MPP_1_AMUX6, CHAN_PATH_SCALING1, AMUX_RSV1,
ADC_DECIMATION_TYPE2, ADC_SCALE_DEFAULT},
};
static struct pm8xxx_adc_properties apq8064_pm8921_adc_data = {
.adc_vdd_reference = 1800, /* milli-voltage for this adc */
.bitresolution = 15,
.bipolar = 0,
};
static struct pm8xxx_adc_platform_data apq8064_pm8921_adc_pdata = {
.adc_channel = apq8064_pm8921_adc_channels_data,
.adc_num_board_channel = ARRAY_SIZE(apq8064_pm8921_adc_channels_data),
.adc_prop = &apq8064_pm8921_adc_data,
.adc_mpp_base = PM8921_MPP_PM_TO_SYS(1),
};
static struct pm8xxx_mpp_platform_data
apq8064_pm8921_mpp_pdata __devinitdata = {
.mpp_base = PM8921_MPP_PM_TO_SYS(1),
};
static struct pm8xxx_gpio_platform_data
apq8064_pm8921_gpio_pdata __devinitdata = {
.gpio_base = PM8921_GPIO_PM_TO_SYS(1),
};
static struct pm8xxx_irq_platform_data
apq8064_pm8921_irq_pdata __devinitdata = {
.irq_base = PM8921_IRQ_BASE,
.devirq = MSM_GPIO_TO_INT(74),
.irq_trigger_flag = IRQF_TRIGGER_LOW,
.dev_id = 0,
};
static struct pm8xxx_rtc_platform_data
apq8064_pm8921_rtc_pdata = {
.rtc_write_enable = false,
.rtc_alarm_powerup = false,
};
static int apq8064_pm8921_therm_mitigation[] = {
1100,
700,
600,
325,
};
static int batt_temp_ctrl_level[] = {
600,
570,
550,
450,
440,
-50,
-80,
-100,
};
/*
* Battery characteristic
* Typ.2100mAh capacity, Li-Ion Polymer 3.8V
* Battery/VDD voltage programmable range, 20mV steps.
*/
#define MAX_VOLTAGE_MV 4360
#define CHG_TERM_MA 100
#define MAX_BATT_CHG_I_MA 900
#define WARM_BATT_CHG_I_MA 400
#define VBATDET_DELTA_MV 50
#define EOC_CHECK_SOC 1
static struct pm8921_charger_platform_data apq8064_pm8921_chg_pdata __devinitdata = {
.safety_time = 512,
.update_time = 60000,
.max_voltage = MAX_VOLTAGE_MV,
.min_voltage = 3200,
.alarm_voltage = 3500,
.resume_voltage_delta = VBATDET_DELTA_MV,
.term_current = CHG_TERM_MA,
.cool_temp = INT_MIN,
.warm_temp = INT_MIN,
.cool_bat_chg_current = 350,
.warm_bat_chg_current = WARM_BATT_CHG_I_MA,
.cold_thr = 1,
.hot_thr = 0,
.ext_batt_temp_monitor = 1,
.temp_check_period = 1,
.max_bat_chg_current = MAX_BATT_CHG_I_MA,
.cool_bat_voltage = 4100,
.warm_bat_voltage = 4100,
.thermal_mitigation = apq8064_pm8921_therm_mitigation,
.thermal_levels = ARRAY_SIZE(apq8064_pm8921_therm_mitigation),
.led_src_config = LED_SRC_5V,
.rconn_mohm = 37,
.eoc_check_soc = EOC_CHECK_SOC,
};
static struct pm8xxx_ccadc_platform_data
apq8064_pm8xxx_ccadc_pdata = {
.r_sense = 10,
.calib_delay_ms = 600000,
};
static struct pm8921_bms_platform_data
apq8064_pm8921_bms_pdata __devinitdata = {
.battery_type = BATT_LGE,
.r_sense = 10,
.v_cutoff = 3500,
.max_voltage_uv = MAX_VOLTAGE_MV * 1000,
.rconn_mohm = 37,
.shutdown_soc_valid_limit = 20,
.adjust_soc_low_threshold = 25,
.chg_term_ua = CHG_TERM_MA * 1000,
.eoc_check_soc = EOC_CHECK_SOC,
};
/* battery data */
static struct single_row_lut batt_2100_fcc_temp = {
.x = {-20, 0, 25, 40, 60 },
.y = {2068, 2064, 2103, 2072, 2084},
.cols = 5
};
static struct single_row_lut batt_2100_fcc_sf = {
.x = {0 },
.y = {100 },
.cols = 1
};
static struct sf_lut batt_2100_rbatt_sf = {
.rows = 28,
.cols = 5,
.row_entries = {-20, 0, 25, 40, 60 },
.percent = {100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50,
45, 40, 35, 30, 25, 20, 15, 10,
9, 8, 7, 6, 5, 4, 3, 2, 1 },
.sf = {
{639,265,100,75,66},
{700,262,104,79,68},
{727,259,106,81,70},
{746,258,106,82,72},
{764,260,106,83,74},
{785,263,106,84,74},
{818,268,100,84,75},
{855,272,99,83,74},
{901,275,100,76,68},
{955,280,103,78,69},
{1016,287,107,80,71},
{1080,297,112,83,73},
{1147,309,116,87,75},
{1221,324,120,90,73},
{1308,345,124,90,72},
{1436,397,125,89,73},
{1673,500,128,87,70},
{2288,587,156,102,78},
{1681,361,140,94,75},
{1886,368,145,95,75},
{2140,377,148,94,73},
{2462,388,151,93,73},
{2877,412,160,96,74},
{3422,473,174,99,77},
{4273,562,195,105,81},
{5469,719,228,112,84},
{8749,1722,274,120,93},
{20487,18766,897,170,1139},
}
};
static struct pc_temp_ocv_lut batt_2100_pc_temp_ocv = {
.rows = 29,
.cols = 5,
.temp = {-20, 0, 25, 40, 60 },
.percent = {100, 95, 90, 85, 80, 75, 70, 65, 60, 55, 50,
45, 40, 35, 30, 25, 20, 15, 10,
9, 8, 7, 6, 5, 4, 3, 2, 1, 0 },
.ocv = {
{4331, 4325, 4327, 4317, 4315},
{4237, 4252, 4261, 4253, 4253},
{4163, 4190, 4202, 4195, 4196},
{4091, 4132, 4147, 4140, 4141},
{4034, 4074, 4093, 4088, 4088},
{3990, 4017, 4043, 4039, 4039},
{3952, 3964, 3992, 3993, 3993},
{3920, 3923, 3937, 3953, 3952},
{3890, 3887, 3895, 3913, 3914},
{3863, 3854, 3860, 3864, 3865},
{3839, 3825, 3831, 3832, 3833},
{3815, 3804, 3809, 3808, 3809},
{3794, 3786, 3791, 3789, 3790},
{3775, 3772, 3775, 3774, 3774},
{3757, 3758, 3764, 3763, 3755},
{3739, 3741, 3750, 3747, 3735},
{3720, 3724, 3725, 3721, 3710},
{3694, 3707, 3689, 3686, 3673},
{3654, 3684, 3674, 3669, 3659},
{3645, 3679, 3670, 3667, 3657},
{3635, 3673, 3664, 3663, 3653},
{3620, 3662, 3648, 3655, 3640},
{3601, 3643, 3612, 3631, 3611},
{3575, 3611, 3563, 3591, 3570},
{3538, 3562, 3501, 3540, 3521},
{3484, 3495, 3430, 3480, 3460},
{3405, 3403, 3347, 3401, 3377},
{3284, 3276, 3223, 3280, 3244},
{3000, 3000, 3000, 3000, 3000}
}
};
static struct sf_lut batt_2100_pc_sf = {
.rows = 1,
.cols = 1,
.row_entries = {0 },
.percent = {100 },
.sf = {
{100 }
}
};
/* used in drivers/power/pm8921-bms.c */
struct pm8921_bms_battery_data lge_2100_mako_data = {
.fcc = 2100,
.fcc_temp_lut = &batt_2100_fcc_temp,
.fcc_sf_lut = &batt_2100_fcc_sf,
.pc_temp_ocv_lut = &batt_2100_pc_temp_ocv,
.pc_sf_lut = &batt_2100_pc_sf,
.rbatt_sf_lut = &batt_2100_rbatt_sf,
.default_rbatt_mohm = 182,
};
static unsigned int keymap[] = {
KEY(0, 0, KEY_VOLUMEDOWN),
KEY(0, 1, KEY_VOLUMEUP),
};
static struct matrix_keymap_data keymap_data = {
.keymap_size = ARRAY_SIZE(keymap),
.keymap = keymap,
};
static __init void mako_fixed_keymap(void) {
if (lge_get_board_revno() < HW_REV_C) {
keymap[0] = KEY(0, 0, KEY_VOLUMEUP);
keymap[1] = KEY(0, 1, KEY_VOLUMEDOWN);
}
}
static struct pm8xxx_keypad_platform_data keypad_data = {
.input_name = "keypad_8064",
.input_phys_device = "keypad_8064/input0",
.num_rows = 1,
.num_cols = 5,
.rows_gpio_start = PM8921_GPIO_PM_TO_SYS(9),
.cols_gpio_start = PM8921_GPIO_PM_TO_SYS(1),
.debounce_ms = 15,
.scan_delay_ms = 32,
.row_hold_ns = 91500,
.wakeup = 1,
.keymap_data = &keymap_data,
};
static struct pm8921_platform_data
apq8064_pm8921_platform_data __devinitdata = {
.regulator_pdatas = msm8064_pm8921_regulator_pdata,
.irq_pdata = &apq8064_pm8921_irq_pdata,
.gpio_pdata = &apq8064_pm8921_gpio_pdata,
.mpp_pdata = &apq8064_pm8921_mpp_pdata,
.rtc_pdata = &apq8064_pm8921_rtc_pdata,
.pwrkey_pdata = &apq8064_pm8921_pwrkey_pdata,
.keypad_pdata = &keypad_data,
.misc_pdata = &apq8064_pm8921_misc_pdata,
.leds_pdata = &apq8064_pm8921_leds_pdata,
.adc_pdata = &apq8064_pm8921_adc_pdata,
.charger_pdata = &apq8064_pm8921_chg_pdata,
.bms_pdata = &apq8064_pm8921_bms_pdata,
.ccadc_pdata = &apq8064_pm8xxx_ccadc_pdata,
};
static struct pm8xxx_irq_platform_data
apq8064_pm8821_irq_pdata __devinitdata = {
.irq_base = PM8821_IRQ_BASE,
.devirq = PM8821_SEC_IRQ_N,
.irq_trigger_flag = IRQF_TRIGGER_HIGH,
.dev_id = 1,
};
static struct pm8xxx_mpp_platform_data
apq8064_pm8821_mpp_pdata __devinitdata = {
.mpp_base = PM8821_MPP_PM_TO_SYS(1),
};
static struct pm8821_platform_data
apq8064_pm8821_platform_data __devinitdata = {
.irq_pdata = &apq8064_pm8821_irq_pdata,
.mpp_pdata = &apq8064_pm8821_mpp_pdata,
};
static struct msm_ssbi_platform_data apq8064_ssbi_pm8921_pdata __devinitdata = {
.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
.slave = {
.name = "pm8921-core",
.platform_data = &apq8064_pm8921_platform_data,
},
};
static struct msm_ssbi_platform_data apq8064_ssbi_pm8821_pdata __devinitdata = {
.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
.slave = {
.name = "pm8821-core",
.platform_data = &apq8064_pm8821_platform_data,
},
};
#ifdef CONFIG_WIRELESS_CHARGER
static struct bq51051b_wlc_platform_data bq51051b_wlc_pmic_pdata = {
.chg_state_gpio = PM8921_GPIO_PM_TO_SYS(26),
.active_n_gpio = PM8921_GPIO_PM_TO_SYS(25),
};
struct platform_device wireless_charger = {
.name = "bq51051b_wlc",
.id = -1,
.dev = {
.platform_data = &bq51051b_wlc_pmic_pdata,
},
};
#endif
static int batt_temp_charger_enable(void)
{
int ret = 0;
pr_info("%s\n", __func__);
ret = pm8921_charger_enable(1);
if (ret)
pr_err("%s: failed to enable charging\n", __func__);
return ret;
}
static int batt_temp_charger_disable(void)
{
int ret = 0;
pr_info("%s\n", __func__);
ret = pm8921_charger_enable(0);
if (ret)
pr_err("%s: failed to disable charging\n", __func__);
return ret;
}
static int batt_temp_ext_power_plugged(void)
{
if (pm8921_is_usb_chg_plugged_in() ||
pm8921_is_dc_chg_plugged_in())
return 1;
else
return 0;
}
static int batt_temp_set_current_limit(int value)
{
int ret = 0;
pr_info("%s: value = %d\n", __func__, value);
ret = pm8921_set_max_battery_charge_current(value);
if (ret)
pr_err("%s: failed to set i limit\n", __func__);
return ret;
}
static int batt_temp_get_current_limit(void)
{
static struct power_supply *psy;
union power_supply_propval ret = {0,};
int rc = 0;
if (psy == NULL) {
psy = power_supply_get_by_name("usb");
if (!psy) {
pr_err("%s: failed to get usb power supply\n", __func__);
return 0;
}
}
rc = psy->get_property(psy, POWER_SUPPLY_PROP_CURRENT_MAX, &ret);
if (rc) {
pr_err("%s: failed to get usb property\n", __func__);
return 0;
}
pr_info("%s: value = %d\n", __func__, ret.intval);
return ret.intval;
}
static int batt_temp_set_state(int health, int i_value)
{
int ret = 0;
ret = pm8921_set_ext_battery_health(health, i_value);
if (ret)
pr_err("%s: failed to set health\n", __func__);
return ret;
}
static struct batt_temp_pdata mako_batt_temp_pada = {
.set_chg_i_limit = batt_temp_set_current_limit,
.get_chg_i_limit = batt_temp_get_current_limit,
.set_health_state = batt_temp_set_state,
.enable_charging = batt_temp_charger_enable,
.disable_charging = batt_temp_charger_disable,
.is_ext_power = batt_temp_ext_power_plugged,
.update_time = 10000, // 10 sec
.temp_level = batt_temp_ctrl_level,
.temp_nums = ARRAY_SIZE(batt_temp_ctrl_level),
.thr_mvolt = 4000, //4.0V
.i_decrease = WARM_BATT_CHG_I_MA,
.i_restore = MAX_BATT_CHG_I_MA,
};
struct platform_device batt_temp_ctrl = {
.name = "batt_temp_ctrl",
.id = -1,
.dev = {
.platform_data = &mako_batt_temp_pada,
},
};
void __init mako_set_adcmap(void)
{
pm8xxx_set_adcmap_btm_threshold(adcmap_btm_threshold,
ARRAY_SIZE(adcmap_btm_threshold));
pm8xxx_set_adcmap_pa_therm(adcmap_pa_therm,
ARRAY_SIZE(adcmap_pa_therm));
/*
pm8xxx_set_adcmap_ntcg_104ef_104fb(adcmap_ntcg_104ef_104fb,
ARRAY_SIZE(adcmap_ntcg_104ef_104fb));
*/
}
void __init apq8064_init_pmic(void)
{
pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
mako_fixed_keymap();
mako_set_adcmap();
mako_fixed_leds();
apq8064_device_ssbi_pmic1.dev.platform_data =
&apq8064_ssbi_pm8921_pdata;
apq8064_device_ssbi_pmic2.dev.platform_data =
&apq8064_ssbi_pm8821_pdata;
apq8064_pm8921_platform_data.num_regulators =
msm8064_pm8921_regulator_pdata_len;
}