Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / power / ab8500_bmdata.c
diff --git a/kernel/drivers/power/ab8500_bmdata.c b/kernel/drivers/power/ab8500_bmdata.c
new file mode 100644 (file)
index 0000000..d298645
--- /dev/null
@@ -0,0 +1,605 @@
+#include <linux/export.h>
+#include <linux/power_supply.h>
+#include <linux/of.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-bm.h>
+
+/*
+ * These are the defined batteries that uses a NTC and ID resistor placed
+ * inside of the battery pack.
+ * Note that the res_to_temp table must be strictly sorted by falling resistance
+ * values to work.
+ */
+const struct abx500_res_to_temp ab8500_temp_tbl_a_thermistor[] = {
+       {-5, 53407},
+       { 0, 48594},
+       { 5, 43804},
+       {10, 39188},
+       {15, 34870},
+       {20, 30933},
+       {25, 27422},
+       {30, 24347},
+       {35, 21694},
+       {40, 19431},
+       {45, 17517},
+       {50, 15908},
+       {55, 14561},
+       {60, 13437},
+       {65, 12500},
+};
+EXPORT_SYMBOL(ab8500_temp_tbl_a_thermistor);
+
+const int ab8500_temp_tbl_a_size = ARRAY_SIZE(ab8500_temp_tbl_a_thermistor);
+EXPORT_SYMBOL(ab8500_temp_tbl_a_size);
+
+const struct abx500_res_to_temp ab8500_temp_tbl_b_thermistor[] = {
+       {-5, 200000},
+       { 0, 159024},
+       { 5, 151921},
+       {10, 144300},
+       {15, 136424},
+       {20, 128565},
+       {25, 120978},
+       {30, 113875},
+       {35, 107397},
+       {40, 101629},
+       {45,  96592},
+       {50,  92253},
+       {55,  88569},
+       {60,  85461},
+       {65,  82869},
+};
+EXPORT_SYMBOL(ab8500_temp_tbl_b_thermistor);
+
+const int ab8500_temp_tbl_b_size = ARRAY_SIZE(ab8500_temp_tbl_b_thermistor);
+EXPORT_SYMBOL(ab8500_temp_tbl_b_size);
+
+static const struct abx500_v_to_cap cap_tbl_a_thermistor[] = {
+       {4171,  100},
+       {4114,   95},
+       {4009,   83},
+       {3947,   74},
+       {3907,   67},
+       {3863,   59},
+       {3830,   56},
+       {3813,   53},
+       {3791,   46},
+       {3771,   33},
+       {3754,   25},
+       {3735,   20},
+       {3717,   17},
+       {3681,   13},
+       {3664,    8},
+       {3651,    6},
+       {3635,    5},
+       {3560,    3},
+       {3408,    1},
+       {3247,    0},
+};
+
+static const struct abx500_v_to_cap cap_tbl_b_thermistor[] = {
+       {4161,  100},
+       {4124,   98},
+       {4044,   90},
+       {4003,   85},
+       {3966,   80},
+       {3933,   75},
+       {3888,   67},
+       {3849,   60},
+       {3813,   55},
+       {3787,   47},
+       {3772,   30},
+       {3751,   25},
+       {3718,   20},
+       {3681,   16},
+       {3660,   14},
+       {3589,   10},
+       {3546,    7},
+       {3495,    4},
+       {3404,    2},
+       {3250,    0},
+};
+
+static const struct abx500_v_to_cap cap_tbl[] = {
+       {4186,  100},
+       {4163,   99},
+       {4114,   95},
+       {4068,   90},
+       {3990,   80},
+       {3926,   70},
+       {3898,   65},
+       {3866,   60},
+       {3833,   55},
+       {3812,   50},
+       {3787,   40},
+       {3768,   30},
+       {3747,   25},
+       {3730,   20},
+       {3705,   15},
+       {3699,   14},
+       {3684,   12},
+       {3672,    9},
+       {3657,    7},
+       {3638,    6},
+       {3556,    4},
+       {3424,    2},
+       {3317,    1},
+       {3094,    0},
+};
+
+/*
+ * Note that the res_to_temp table must be strictly sorted by falling
+ * resistance values to work.
+ */
+static const struct abx500_res_to_temp temp_tbl[] = {
+       {-5, 214834},
+       { 0, 162943},
+       { 5, 124820},
+       {10,  96520},
+       {15,  75306},
+       {20,  59254},
+       {25,  47000},
+       {30,  37566},
+       {35,  30245},
+       {40,  24520},
+       {45,  20010},
+       {50,  16432},
+       {55,  13576},
+       {60,  11280},
+       {65,   9425},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+static const struct batres_vs_temp temp_to_batres_tbl_thermistor[] = {
+       { 40, 120},
+       { 30, 135},
+       { 20, 165},
+       { 10, 230},
+       { 00, 325},
+       {-10, 445},
+       {-20, 595},
+};
+
+/*
+ * Note that the batres_vs_temp table must be strictly sorted by falling
+ * temperature values to work.
+ */
+static const struct batres_vs_temp temp_to_batres_tbl_ext_thermistor[] = {
+       { 60, 300},
+       { 30, 300},
+       { 20, 300},
+       { 10, 300},
+       { 00, 300},
+       {-10, 300},
+       {-20, 300},
+};
+
+/* battery resistance table for LI ION 9100 battery */
+static const struct batres_vs_temp temp_to_batres_tbl_9100[] = {
+       { 60, 180},
+       { 30, 180},
+       { 20, 180},
+       { 10, 180},
+       { 00, 180},
+       {-10, 180},
+       {-20, 180},
+};
+
+static struct abx500_battery_type bat_type_thermistor[] = {
+       [BATTERY_UNKNOWN] = {
+               /* First element always represent the UNKNOWN battery */
+               .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+               .resis_high = 0,
+               .resis_low = 0,
+               .battery_resistance = 300,
+               .charge_full_design = 612,
+               .nominal_voltage = 3700,
+               .termination_vol = 4050,
+               .termination_curr = 200,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 400,
+               .normal_vol_lvl = 4100,
+               .maint_a_cur_lvl = 400,
+               .maint_a_vol_lvl = 4050,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 400,
+               .maint_b_vol_lvl = 4000,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+               .r_to_t_tbl = temp_tbl,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+               .v_to_cap_tbl = cap_tbl,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+       },
+       {
+               .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+               .resis_high = 53407,
+               .resis_low = 12500,
+               .battery_resistance = 300,
+               .charge_full_design = 900,
+               .nominal_voltage = 3600,
+               .termination_vol = 4150,
+               .termination_curr = 80,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 700,
+               .normal_vol_lvl = 4200,
+               .maint_a_cur_lvl = 600,
+               .maint_a_vol_lvl = 4150,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 600,
+               .maint_b_vol_lvl = 4100,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(ab8500_temp_tbl_a_thermistor),
+               .r_to_t_tbl = ab8500_temp_tbl_a_thermistor,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_a_thermistor),
+               .v_to_cap_tbl = cap_tbl_a_thermistor,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+
+       },
+       {
+               .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+               .resis_high = 200000,
+               .resis_low = 82869,
+               .battery_resistance = 300,
+               .charge_full_design = 900,
+               .nominal_voltage = 3600,
+               .termination_vol = 4150,
+               .termination_curr = 80,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 700,
+               .normal_vol_lvl = 4200,
+               .maint_a_cur_lvl = 600,
+               .maint_a_vol_lvl = 4150,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 600,
+               .maint_b_vol_lvl = 4100,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(ab8500_temp_tbl_b_thermistor),
+               .r_to_t_tbl = ab8500_temp_tbl_b_thermistor,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl_b_thermistor),
+               .v_to_cap_tbl = cap_tbl_b_thermistor,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+       },
+};
+
+static struct abx500_battery_type bat_type_ext_thermistor[] = {
+       [BATTERY_UNKNOWN] = {
+               /* First element always represent the UNKNOWN battery */
+               .name = POWER_SUPPLY_TECHNOLOGY_UNKNOWN,
+               .resis_high = 0,
+               .resis_low = 0,
+               .battery_resistance = 300,
+               .charge_full_design = 612,
+               .nominal_voltage = 3700,
+               .termination_vol = 4050,
+               .termination_curr = 200,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 400,
+               .normal_vol_lvl = 4100,
+               .maint_a_cur_lvl = 400,
+               .maint_a_vol_lvl = 4050,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 400,
+               .maint_b_vol_lvl = 4000,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+               .r_to_t_tbl = temp_tbl,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+               .v_to_cap_tbl = cap_tbl,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+       },
+/*
+ * These are the batteries that doesn't have an internal NTC resistor to measure
+ * its temperature. The temperature in this case is measure with a NTC placed
+ * near the battery but on the PCB.
+ */
+       {
+               .name = POWER_SUPPLY_TECHNOLOGY_LIPO,
+               .resis_high = 76000,
+               .resis_low = 53000,
+               .battery_resistance = 300,
+               .charge_full_design = 900,
+               .nominal_voltage = 3700,
+               .termination_vol = 4150,
+               .termination_curr = 100,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 700,
+               .normal_vol_lvl = 4200,
+               .maint_a_cur_lvl = 600,
+               .maint_a_vol_lvl = 4150,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 600,
+               .maint_b_vol_lvl = 4100,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+               .r_to_t_tbl = temp_tbl,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+               .v_to_cap_tbl = cap_tbl,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+       },
+       {
+               .name = POWER_SUPPLY_TECHNOLOGY_LION,
+               .resis_high = 30000,
+               .resis_low = 10000,
+               .battery_resistance = 300,
+               .charge_full_design = 950,
+               .nominal_voltage = 3700,
+               .termination_vol = 4150,
+               .termination_curr = 100,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 700,
+               .normal_vol_lvl = 4200,
+               .maint_a_cur_lvl = 600,
+               .maint_a_vol_lvl = 4150,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 600,
+               .maint_b_vol_lvl = 4100,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+               .r_to_t_tbl = temp_tbl,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+               .v_to_cap_tbl = cap_tbl,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+       },
+       {
+               .name = POWER_SUPPLY_TECHNOLOGY_LION,
+               .resis_high = 95000,
+               .resis_low = 76001,
+               .battery_resistance = 300,
+               .charge_full_design = 950,
+               .nominal_voltage = 3700,
+               .termination_vol = 4150,
+               .termination_curr = 100,
+               .recharge_cap = 95,
+               .normal_cur_lvl = 700,
+               .normal_vol_lvl = 4200,
+               .maint_a_cur_lvl = 600,
+               .maint_a_vol_lvl = 4150,
+               .maint_a_chg_timer_h = 60,
+               .maint_b_cur_lvl = 600,
+               .maint_b_vol_lvl = 4100,
+               .maint_b_chg_timer_h = 200,
+               .low_high_cur_lvl = 300,
+               .low_high_vol_lvl = 4000,
+               .n_temp_tbl_elements = ARRAY_SIZE(temp_tbl),
+               .r_to_t_tbl = temp_tbl,
+               .n_v_cap_tbl_elements = ARRAY_SIZE(cap_tbl),
+               .v_to_cap_tbl = cap_tbl,
+               .n_batres_tbl_elements = ARRAY_SIZE(temp_to_batres_tbl_thermistor),
+               .batres_tbl = temp_to_batres_tbl_thermistor,
+       },
+};
+
+static const struct abx500_bm_capacity_levels cap_levels = {
+       .critical       = 2,
+       .low            = 10,
+       .normal         = 70,
+       .high           = 95,
+       .full           = 100,
+};
+
+static const struct abx500_fg_parameters fg = {
+       .recovery_sleep_timer = 10,
+       .recovery_total_time = 100,
+       .init_timer = 1,
+       .init_discard_time = 5,
+       .init_total_time = 40,
+       .high_curr_time = 60,
+       .accu_charging = 30,
+       .accu_high_curr = 30,
+       .high_curr_threshold = 50,
+       .lowbat_threshold = 3100,
+       .battok_falling_th_sel0 = 2860,
+       .battok_raising_th_sel1 = 2860,
+       .maint_thres = 95,
+       .user_cap_limit = 15,
+       .pcut_enable = 1,
+       .pcut_max_time = 127,
+       .pcut_flag_time = 112,
+       .pcut_max_restart = 15,
+       .pcut_debounce_time = 2,
+};
+
+static const struct abx500_maxim_parameters ab8500_maxi_params = {
+       .ena_maxi = true,
+       .chg_curr = 910,
+       .wait_cycles = 10,
+       .charger_curr_step = 100,
+};
+
+static const struct abx500_maxim_parameters abx540_maxi_params = {
+        .ena_maxi = true,
+        .chg_curr = 3000,
+        .wait_cycles = 10,
+        .charger_curr_step = 200,
+};
+
+static const struct abx500_bm_charger_parameters chg = {
+       .usb_volt_max           = 5500,
+       .usb_curr_max           = 1500,
+       .ac_volt_max            = 7500,
+       .ac_curr_max            = 1500,
+};
+
+/*
+ * This array maps the raw hex value to charger output current used by the
+ * AB8500 values
+ */
+static int ab8500_charge_output_curr_map[] = {
+        100,    200,    300,    400,    500,    600,    700,    800,
+        900,    1000,   1100,   1200,   1300,   1400,   1500,   1500,
+};
+
+static int ab8540_charge_output_curr_map[] = {
+        0,      0,      0,      75,     100,    125,    150,    175,
+        200,    225,    250,    275,    300,    325,    350,    375,
+        400,    425,    450,    475,    500,    525,    550,    575,
+        600,    625,    650,    675,    700,    725,    750,    775,
+        800,    825,    850,    875,    900,    925,    950,    975,
+        1000,   1025,   1050,   1075,   1100,   1125,   1150,   1175,
+        1200,   1225,   1250,   1275,   1300,   1325,   1350,   1375,
+        1400,   1425,   1450,   1500,   1600,   1700,   1900,   2000,
+};
+
+/*
+ * This array maps the raw hex value to charger input current used by the
+ * AB8500 values
+ */
+static int ab8500_charge_input_curr_map[] = {
+        50,     98,     193,    290,    380,    450,    500,    600,
+        700,    800,    900,    1000,   1100,   1300,   1400,   1500,
+};
+
+static int ab8540_charge_input_curr_map[] = {
+        25,     50,     75,     100,    125,    150,    175,    200,
+        225,    250,    275,    300,    325,    350,    375,    400,
+        425,    450,    475,    500,    525,    550,    575,    600,
+        625,    650,    675,    700,    725,    750,    775,    800,
+        825,    850,    875,    900,    925,    950,    975,    1000,
+        1025,   1050,   1075,   1100,   1125,   1150,   1175,   1200,
+        1225,   1250,   1275,   1300,   1325,   1350,   1375,   1400,
+        1425,   1450,   1475,   1500,   1500,   1500,   1500,   1500,
+};
+
+struct abx500_bm_data ab8500_bm_data = {
+       .temp_under             = 3,
+       .temp_low               = 8,
+       .temp_high              = 43,
+       .temp_over              = 48,
+       .main_safety_tmr_h      = 4,
+       .temp_interval_chg      = 20,
+       .temp_interval_nochg    = 120,
+       .usb_safety_tmr_h       = 4,
+       .bkup_bat_v             = BUP_VCH_SEL_2P6V,
+       .bkup_bat_i             = BUP_ICH_SEL_150UA,
+       .no_maintenance         = false,
+       .capacity_scaling       = false,
+       .adc_therm              = ABx500_ADC_THERM_BATCTRL,
+       .chg_unknown_bat        = false,
+       .enable_overshoot       = false,
+       .fg_res                 = 100,
+       .cap_levels             = &cap_levels,
+       .bat_type               = bat_type_thermistor,
+       .n_btypes               = ARRAY_SIZE(bat_type_thermistor),
+       .batt_id                = 0,
+       .interval_charging      = 5,
+       .interval_not_charging  = 120,
+       .temp_hysteresis        = 3,
+       .gnd_lift_resistance    = 34,
+       .chg_output_curr        = ab8500_charge_output_curr_map,
+       .n_chg_out_curr         = ARRAY_SIZE(ab8500_charge_output_curr_map),
+       .maxi                   = &ab8500_maxi_params,
+       .chg_params             = &chg,
+       .fg_params              = &fg,
+        .chg_input_curr         = ab8500_charge_input_curr_map,
+        .n_chg_in_curr          = ARRAY_SIZE(ab8500_charge_input_curr_map),
+};
+
+struct abx500_bm_data ab8540_bm_data = {
+        .temp_under             = 3,
+        .temp_low               = 8,
+        .temp_high              = 43,
+        .temp_over              = 48,
+        .main_safety_tmr_h      = 4,
+        .temp_interval_chg      = 20,
+        .temp_interval_nochg    = 120,
+        .usb_safety_tmr_h       = 4,
+        .bkup_bat_v             = BUP_VCH_SEL_2P6V,
+        .bkup_bat_i             = BUP_ICH_SEL_150UA,
+        .no_maintenance         = false,
+        .capacity_scaling       = false,
+        .adc_therm              = ABx500_ADC_THERM_BATCTRL,
+        .chg_unknown_bat        = false,
+        .enable_overshoot       = false,
+        .fg_res                 = 100,
+        .cap_levels             = &cap_levels,
+        .bat_type               = bat_type_thermistor,
+        .n_btypes               = ARRAY_SIZE(bat_type_thermistor),
+        .batt_id                = 0,
+        .interval_charging      = 5,
+        .interval_not_charging  = 120,
+        .temp_hysteresis        = 3,
+        .gnd_lift_resistance    = 0,
+        .maxi                   = &abx540_maxi_params,
+        .chg_params             = &chg,
+        .fg_params              = &fg,
+        .chg_output_curr        = ab8540_charge_output_curr_map,
+        .n_chg_out_curr         = ARRAY_SIZE(ab8540_charge_output_curr_map),
+        .chg_input_curr         = ab8540_charge_input_curr_map,
+        .n_chg_in_curr          = ARRAY_SIZE(ab8540_charge_input_curr_map),
+};
+
+int ab8500_bm_of_probe(struct device *dev,
+                      struct device_node *np,
+                      struct abx500_bm_data *bm)
+{
+       const struct batres_vs_temp *tmp_batres_tbl;
+       struct device_node *battery_node;
+       const char *btech;
+       int i;
+
+       /* get phandle to 'battery-info' node */
+       battery_node = of_parse_phandle(np, "battery", 0);
+       if (!battery_node) {
+               dev_err(dev, "battery node or reference missing\n");
+               return -EINVAL;
+       }
+
+       btech = of_get_property(battery_node, "stericsson,battery-type", NULL);
+       if (!btech) {
+               dev_warn(dev, "missing property battery-name/type\n");
+               return -EINVAL;
+       }
+
+       if (strncmp(btech, "LION", 4) == 0) {
+               bm->no_maintenance  = true;
+               bm->chg_unknown_bat = true;
+               bm->bat_type[BATTERY_UNKNOWN].charge_full_design = 2600;
+               bm->bat_type[BATTERY_UNKNOWN].termination_vol    = 4150;
+               bm->bat_type[BATTERY_UNKNOWN].recharge_cap       = 95;
+               bm->bat_type[BATTERY_UNKNOWN].normal_cur_lvl     = 520;
+               bm->bat_type[BATTERY_UNKNOWN].normal_vol_lvl     = 4200;
+       }
+
+       if (of_property_read_bool(battery_node, "thermistor-on-batctrl")) {
+               if (strncmp(btech, "LION", 4) == 0)
+                       tmp_batres_tbl = temp_to_batres_tbl_9100;
+               else
+                       tmp_batres_tbl = temp_to_batres_tbl_thermistor;
+       } else {
+               bm->n_btypes   = 4;
+               bm->bat_type   = bat_type_ext_thermistor;
+               bm->adc_therm  = ABx500_ADC_THERM_BATTEMP;
+               tmp_batres_tbl = temp_to_batres_tbl_ext_thermistor;
+       }
+
+       /* select the battery resolution table */
+       for (i = 0; i < bm->n_btypes; ++i)
+               bm->bat_type[i].batres_tbl = tmp_batres_tbl;
+
+       of_node_put(battery_node);
+
+       return 0;
+}