]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/power/abx500_chargalg.c
Merge branch 'for-anton' of git://git.linaro.org/people/ljones/linux-3.0-ux500
[karo-tx-linux.git] / drivers / power / abx500_chargalg.c
index 2970891460641177f53449dc1ff32b33ed26a375..8b69da0ae5af76ac983830db7e0427a7e638146a 100644 (file)
@@ -207,7 +207,7 @@ enum maxim_ret {
  * @chg_info:          information about connected charger types
  * @batt_data:         data of the battery
  * @susp_status:       current charger suspension status
- * @bat:               pointer to the abx500_bm platform data
+ * @bm:                Platform specific battery management information
  * @chargalg_psy:      structure that holds the battery properties exposed by
  *                     the charging algorithm
  * @events:            structure for information about events triggered
@@ -232,7 +232,7 @@ struct abx500_chargalg {
        struct abx500_chargalg_charger_info chg_info;
        struct abx500_chargalg_battery_data batt_data;
        struct abx500_chargalg_suspension_status susp_status;
-       struct abx500_bm_data *bat;
+       struct abx500_bm_data *bm;
        struct power_supply chargalg_psy;
        struct ux500_charger *ac_chg;
        struct ux500_charger *usb_chg;
@@ -367,13 +367,13 @@ static void abx500_chargalg_start_safety_timer(struct abx500_chargalg *di)
        case AC_CHG:
                timer_expiration =
                round_jiffies(jiffies +
-                       (di->bat->main_safety_tmr_h * 3600 * HZ));
+                       (di->bm->main_safety_tmr_h * 3600 * HZ));
                break;
 
        case USB_CHG:
                timer_expiration =
                round_jiffies(jiffies +
-                       (di->bat->usb_safety_tmr_h * 3600 * HZ));
+                       (di->bm->usb_safety_tmr_h * 3600 * HZ));
                break;
 
        default:
@@ -638,32 +638,32 @@ static void abx500_chargalg_start_charging(struct abx500_chargalg *di,
  */
 static void abx500_chargalg_check_temp(struct abx500_chargalg *di)
 {
-       if (di->batt_data.temp > (di->bat->temp_low + di->t_hyst_norm) &&
-               di->batt_data.temp < (di->bat->temp_high - di->t_hyst_norm)) {
+       if (di->batt_data.temp > (di->bm->temp_low + di->t_hyst_norm) &&
+               di->batt_data.temp < (di->bm->temp_high - di->t_hyst_norm)) {
                /* Temp OK! */
                di->events.btemp_underover = false;
                di->events.btemp_lowhigh = false;
                di->t_hyst_norm = 0;
                di->t_hyst_lowhigh = 0;
        } else {
-               if (((di->batt_data.temp >= di->bat->temp_high) &&
+               if (((di->batt_data.temp >= di->bm->temp_high) &&
                        (di->batt_data.temp <
-                               (di->bat->temp_over - di->t_hyst_lowhigh))) ||
+                               (di->bm->temp_over - di->t_hyst_lowhigh))) ||
                        ((di->batt_data.temp >
-                               (di->bat->temp_under + di->t_hyst_lowhigh)) &&
-                       (di->batt_data.temp <= di->bat->temp_low))) {
+                               (di->bm->temp_under + di->t_hyst_lowhigh)) &&
+                       (di->batt_data.temp <= di->bm->temp_low))) {
                        /* TEMP minor!!!!! */
                        di->events.btemp_underover = false;
                        di->events.btemp_lowhigh = true;
-                       di->t_hyst_norm = di->bat->temp_hysteresis;
+                       di->t_hyst_norm = di->bm->temp_hysteresis;
                        di->t_hyst_lowhigh = 0;
-               } else if (di->batt_data.temp <= di->bat->temp_under ||
-                       di->batt_data.temp >= di->bat->temp_over) {
+               } else if (di->batt_data.temp <= di->bm->temp_under ||
+                       di->batt_data.temp >= di->bm->temp_over) {
                        /* TEMP major!!!!! */
                        di->events.btemp_underover = true;
                        di->events.btemp_lowhigh = false;
                        di->t_hyst_norm = 0;
-                       di->t_hyst_lowhigh = di->bat->temp_hysteresis;
+                       di->t_hyst_lowhigh = di->bm->temp_hysteresis;
                } else {
                /* Within hysteresis */
                dev_dbg(di->dev, "Within hysteresis limit temp: %d "
@@ -682,12 +682,12 @@ static void abx500_chargalg_check_temp(struct abx500_chargalg *di)
  */
 static void abx500_chargalg_check_charger_voltage(struct abx500_chargalg *di)
 {
-       if (di->chg_info.usb_volt > di->bat->chg_params->usb_volt_max)
+       if (di->chg_info.usb_volt > di->bm->chg_params->usb_volt_max)
                di->chg_info.usb_chg_ok = false;
        else
                di->chg_info.usb_chg_ok = true;
 
-       if (di->chg_info.ac_volt > di->bat->chg_params->ac_volt_max)
+       if (di->chg_info.ac_volt > di->bm->chg_params->ac_volt_max)
                di->chg_info.ac_chg_ok = false;
        else
                di->chg_info.ac_chg_ok = true;
@@ -707,10 +707,10 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
        if (di->charge_status == POWER_SUPPLY_STATUS_CHARGING &&
                di->charge_state == STATE_NORMAL &&
                !di->maintenance_chg && (di->batt_data.volt >=
-               di->bat->bat_type[di->bat->batt_id].termination_vol ||
+               di->bm->bat_type[di->bm->batt_id].termination_vol ||
                di->events.usb_cv_active || di->events.ac_cv_active) &&
                di->batt_data.avg_curr <
-               di->bat->bat_type[di->bat->batt_id].termination_curr &&
+               di->bm->bat_type[di->bm->batt_id].termination_curr &&
                di->batt_data.avg_curr > 0) {
                if (++di->eoc_cnt >= EOC_COND_CNT) {
                        di->eoc_cnt = 0;
@@ -733,12 +733,12 @@ static void abx500_chargalg_end_of_charge(struct abx500_chargalg *di)
 static void init_maxim_chg_curr(struct abx500_chargalg *di)
 {
        di->ccm.original_iset =
-               di->bat->bat_type[di->bat->batt_id].normal_cur_lvl;
+               di->bm->bat_type[di->bm->batt_id].normal_cur_lvl;
        di->ccm.current_iset =
-               di->bat->bat_type[di->bat->batt_id].normal_cur_lvl;
-       di->ccm.test_delta_i = di->bat->maxi->charger_curr_step;
-       di->ccm.max_current = di->bat->maxi->chg_curr;
-       di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
+               di->bm->bat_type[di->bm->batt_id].normal_cur_lvl;
+       di->ccm.test_delta_i = di->bm->maxi->charger_curr_step;
+       di->ccm.max_current = di->bm->maxi->chg_curr;
+       di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
        di->ccm.level = 0;
 }
 
@@ -755,7 +755,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
 {
        int delta_i;
 
-       if (!di->bat->maxi->ena_maxi)
+       if (!di->bm->maxi->ena_maxi)
                return MAXIM_RET_NOACTION;
 
        delta_i = di->ccm.original_iset - di->batt_data.inst_curr;
@@ -766,7 +766,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
                if (di->ccm.wait_cnt == 0) {
                        dev_dbg(di->dev, "lowering current\n");
                        di->ccm.wait_cnt++;
-                       di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
+                       di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
                        di->ccm.max_current =
                                di->ccm.current_iset - di->ccm.test_delta_i;
                        di->ccm.current_iset = di->ccm.max_current;
@@ -791,7 +791,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
                if (di->ccm.current_iset == di->ccm.original_iset)
                        return MAXIM_RET_NOACTION;
 
-               di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
+               di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
                di->ccm.current_iset = di->ccm.original_iset;
                di->ccm.level = 0;
 
@@ -803,7 +803,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
                di->ccm.max_current) {
                if (di->ccm.condition_cnt-- == 0) {
                        /* Increse the iset with cco.test_delta_i */
-                       di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
+                       di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
                        di->ccm.current_iset += di->ccm.test_delta_i;
                        di->ccm.level++;
                        dev_dbg(di->dev, " Maximization needed, increase"
@@ -818,7 +818,7 @@ static enum maxim_ret abx500_chargalg_chg_curr_maxim(struct abx500_chargalg *di)
                        return MAXIM_RET_NOACTION;
                }
        }  else {
-               di->ccm.condition_cnt = di->bat->maxi->wait_cycles;
+               di->ccm.condition_cnt = di->bm->maxi->wait_cycles;
                return MAXIM_RET_NOACTION;
        }
 }
@@ -838,7 +838,7 @@ static void handle_maxim_chg_curr(struct abx500_chargalg *di)
                break;
        case MAXIM_RET_IBAT_TOO_HIGH:
                result = abx500_chargalg_update_chg_curr(di,
-                       di->bat->bat_type[di->bat->batt_id].normal_cur_lvl);
+                       di->bm->bat_type[di->bm->batt_id].normal_cur_lvl);
                if (result)
                        dev_err(di->dev, "failed to set chg curr\n");
                break;
@@ -1210,7 +1210,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
         * this way
         */
        if (!charger_status ||
-               (di->events.batt_unknown && !di->bat->chg_unknown_bat)) {
+               (di->events.batt_unknown && !di->bm->chg_unknown_bat)) {
                if (di->charge_state != STATE_HANDHELD) {
                        di->events.safety_timer_expired = false;
                        abx500_chargalg_state_to(di, STATE_HANDHELD_INIT);
@@ -1394,8 +1394,8 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
 
        case STATE_NORMAL_INIT:
                abx500_chargalg_start_charging(di,
-                       di->bat->bat_type[di->bat->batt_id].normal_vol_lvl,
-                       di->bat->bat_type[di->bat->batt_id].normal_cur_lvl);
+                       di->bm->bat_type[di->bm->batt_id].normal_vol_lvl,
+                       di->bm->bat_type[di->bm->batt_id].normal_cur_lvl);
                abx500_chargalg_state_to(di, STATE_NORMAL);
                abx500_chargalg_start_safety_timer(di);
                abx500_chargalg_stop_maintenance_timer(di);
@@ -1411,7 +1411,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
                handle_maxim_chg_curr(di);
                if (di->charge_status == POWER_SUPPLY_STATUS_FULL &&
                        di->maintenance_chg) {
-                       if (di->bat->no_maintenance)
+                       if (di->bm->no_maintenance)
                                abx500_chargalg_state_to(di,
                                        STATE_WAIT_FOR_RECHARGE_INIT);
                        else
@@ -1429,7 +1429,7 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
 
        case STATE_WAIT_FOR_RECHARGE:
                if (di->batt_data.volt <=
-                       di->bat->bat_type[di->bat->batt_id].recharge_vol) {
+                       di->bm->bat_type[di->bm->batt_id].recharge_vol) {
                        if (di->rch_cnt-- == 0)
                                abx500_chargalg_state_to(di, STATE_NORMAL_INIT);
                } else
@@ -1439,13 +1439,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
        case STATE_MAINTENANCE_A_INIT:
                abx500_chargalg_stop_safety_timer(di);
                abx500_chargalg_start_maintenance_timer(di,
-                       di->bat->bat_type[
-                               di->bat->batt_id].maint_a_chg_timer_h);
+                       di->bm->bat_type[
+                               di->bm->batt_id].maint_a_chg_timer_h);
                abx500_chargalg_start_charging(di,
-                       di->bat->bat_type[
-                               di->bat->batt_id].maint_a_vol_lvl,
-                       di->bat->bat_type[
-                               di->bat->batt_id].maint_a_cur_lvl);
+                       di->bm->bat_type[
+                               di->bm->batt_id].maint_a_vol_lvl,
+                       di->bm->bat_type[
+                               di->bm->batt_id].maint_a_cur_lvl);
                abx500_chargalg_state_to(di, STATE_MAINTENANCE_A);
                power_supply_changed(&di->chargalg_psy);
                /* Intentional fallthrough*/
@@ -1459,13 +1459,13 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
 
        case STATE_MAINTENANCE_B_INIT:
                abx500_chargalg_start_maintenance_timer(di,
-                       di->bat->bat_type[
-                               di->bat->batt_id].maint_b_chg_timer_h);
+                       di->bm->bat_type[
+                               di->bm->batt_id].maint_b_chg_timer_h);
                abx500_chargalg_start_charging(di,
-                       di->bat->bat_type[
-                               di->bat->batt_id].maint_b_vol_lvl,
-                       di->bat->bat_type[
-                               di->bat->batt_id].maint_b_cur_lvl);
+                       di->bm->bat_type[
+                               di->bm->batt_id].maint_b_vol_lvl,
+                       di->bm->bat_type[
+                               di->bm->batt_id].maint_b_cur_lvl);
                abx500_chargalg_state_to(di, STATE_MAINTENANCE_B);
                power_supply_changed(&di->chargalg_psy);
                /* Intentional fallthrough*/
@@ -1479,10 +1479,10 @@ static void abx500_chargalg_algorithm(struct abx500_chargalg *di)
 
        case STATE_TEMP_LOWHIGH_INIT:
                abx500_chargalg_start_charging(di,
-                       di->bat->bat_type[
-                               di->bat->batt_id].low_high_vol_lvl,
-                       di->bat->bat_type[
-                               di->bat->batt_id].low_high_cur_lvl);
+                       di->bm->bat_type[
+                               di->bm->batt_id].low_high_vol_lvl,
+                       di->bm->bat_type[
+                               di->bm->batt_id].low_high_cur_lvl);
                abx500_chargalg_stop_maintenance_timer(di);
                di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
                abx500_chargalg_state_to(di, STATE_TEMP_LOWHIGH);
@@ -1543,11 +1543,11 @@ static void abx500_chargalg_periodic_work(struct work_struct *work)
        if (di->chg_info.conn_chg)
                queue_delayed_work(di->chargalg_wq,
                        &di->chargalg_periodic_work,
-                       di->bat->interval_charging * HZ);
+                       di->bm->interval_charging * HZ);
        else
                queue_delayed_work(di->chargalg_wq,
                        &di->chargalg_periodic_work,
-                       di->bat->interval_not_charging * HZ);
+                       di->bm->interval_not_charging * HZ);
 }
 
 /**
@@ -1614,7 +1614,7 @@ static int abx500_chargalg_get_property(struct power_supply *psy,
                if (di->events.batt_ovv) {
                        val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
                } else if (di->events.btemp_underover) {
-                       if (di->batt_data.temp <= di->bat->temp_under)
+                       if (di->batt_data.temp <= di->bm->temp_under)
                                val->intval = POWER_SUPPLY_HEALTH_COLD;
                        else
                                val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
@@ -1806,6 +1806,7 @@ static char *supply_interface[] = {
 static int abx500_chargalg_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
+       struct abx500_bm_data *plat = pdev->dev.platform_data;
        struct abx500_chargalg *di;
        int ret = 0;
 
@@ -1814,21 +1815,19 @@ static int abx500_chargalg_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__);
                return -ENOMEM;
        }
-       di->bat = pdev->mfd_cell->platform_data;
-       if (!di->bat) {
-               if (np) {
-                       ret = bmdevs_of_probe(&pdev->dev, np, &di->bat);
-                       if (ret) {
-                               dev_err(&pdev->dev,
-                                       "failed to get battery information\n");
-                               return ret;
-                       }
-               } else {
-                       dev_err(&pdev->dev, "missing dt node for ab8500_chargalg\n");
-                       return -EINVAL;
+
+       if (!plat) {
+               dev_err(&pdev->dev, "no battery management data supplied\n");
+               return -EINVAL;
+       }
+       di->bm = plat;
+
+       if (np) {
+               ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get battery information\n");
+                       return ret;
                }
-       } else {
-               dev_info(&pdev->dev, "falling back to legacy platform data\n");
        }
 
        /* get device struct */