static int smb347_set_current_limits(struct smb347_charger *smb) { int ret, val; ret = smb347_read(smb, CFG_CURRENT_LIMIT); if (ret < 0) return ret; if (smb->mains_current_limit) { val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), smb->mains_current_limit); if (val < 0) return val; ret &= ~CFG_CURRENT_LIMIT_DC_MASK; ret |= val << CFG_CURRENT_LIMIT_DC_SHIFT; } if (smb->pdata->usb_hc_current_limit) { val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl), smb->pdata->usb_hc_current_limit); if (val < 0) return val; ret &= ~CFG_CURRENT_LIMIT_USB_MASK; ret |= val; } return smb347_write(smb, CFG_CURRENT_LIMIT, ret); }
static int smb347_set_charge_current(struct smb347_charger *smb) { int ret, val; ret = smb347_read(smb, CFG_CHARGE_CURRENT); if (ret < 0) return ret; if (smb->pdata->max_charge_current) { val = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl), smb->pdata->max_charge_current); if (val < 0) return val; ret &= ~CFG_CHARGE_CURRENT_FCC_MASK; ret |= val << CFG_CHARGE_CURRENT_FCC_SHIFT; } if (smb->pdata->pre_charge_current) { val = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl), smb->pdata->pre_charge_current); if (val < 0) return val; ret &= ~CFG_CHARGE_CURRENT_PCC_MASK; ret |= val << CFG_CHARGE_CURRENT_PCC_SHIFT; } if (smb->pdata->termination_current) { val = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl), smb->pdata->termination_current); if (val < 0) return val; ret &= ~CFG_CHARGE_CURRENT_TC_MASK; ret |= val; } return smb347_write(smb, CFG_CHARGE_CURRENT, ret); }
static int smb347_set_current_limits(struct smb347_device *smb_dev) { char ret; if (smb_dev->info->max_current) { xhc_printk("xhc_test_smb_dev->info->max_current = %d\n", smb_dev->info->max_current); ret = current_to_hw (icl_tbl, ARRAY_SIZE(icl_tbl), smb_dev->info->max_current); if (ret < 0) { return ret; } ret = (ret << 4) + ret; xhc_printk("ret = %x\n", ret); ret = smb347_write(smb_dev->client, 0x01, &ret, 1); if (ret < 0) { return ret; } } return 0; }
static int smb347_set_temp_limits(struct smb347_charger *smb) { bool enable_therm_monitor = false; int ret, val; if (smb->pdata->chip_temp_threshold) { val = smb->pdata->chip_temp_threshold; /* degree C */ val = clamp_val(val, 100, 130) - 100; val /= 10; ret = smb347_read(smb, CFG_OTG); if (ret < 0) return ret; ret &= ~CFG_OTG_TEMP_THRESHOLD_MASK; ret |= val << CFG_OTG_TEMP_THRESHOLD_SHIFT; ret = smb347_write(smb, CFG_OTG, ret); if (ret < 0) return ret; } ret = smb347_read(smb, CFG_TEMP_LIMIT); if (ret < 0) return ret; if (smb->pdata->soft_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->soft_cold_temp_limit; val = clamp_val(val, 0, 15); val /= 5; /* this goes from higher to lower so invert the value */ val = ~val & 0x3; ret &= ~CFG_TEMP_LIMIT_SOFT_COLD_MASK; ret |= val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT; enable_therm_monitor = true; } if (smb->pdata->soft_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->soft_hot_temp_limit; val = clamp_val(val, 40, 55) - 40; val /= 5; ret &= ~CFG_TEMP_LIMIT_SOFT_HOT_MASK; ret |= val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT; enable_therm_monitor = true; } if (smb->pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->hard_cold_temp_limit; val = clamp_val(val, -5, 10) + 5; val /= 5; /* this goes from higher to lower so invert the value */ val = ~val & 0x3; ret &= ~CFG_TEMP_LIMIT_HARD_COLD_MASK; ret |= val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT; enable_therm_monitor = true; } if (smb->pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->hard_hot_temp_limit; val = clamp_val(val, 50, 65) - 50; val /= 5; ret &= ~CFG_TEMP_LIMIT_HARD_HOT_MASK; ret |= val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT; enable_therm_monitor = true; } ret = smb347_write(smb, CFG_TEMP_LIMIT, ret); if (ret < 0) return ret; /* * If any of the temperature limits are set, we also enable the * thermistor monitoring. * * When soft limits are hit, the device will start to compensate * current and/or voltage depending on the configuration. * * When hard limit is hit, the device will suspend charging * depending on the configuration. */ if (enable_therm_monitor) { ret = smb347_read(smb, CFG_THERM); if (ret < 0) return ret; ret &= ~CFG_THERM_MONITOR_DISABLED; ret = smb347_write(smb, CFG_THERM, ret); if (ret < 0) return ret; } if (smb->pdata->suspend_on_hard_temp_limit) { ret = smb347_read(smb, CFG_SYSOK); if (ret < 0) return ret; ret &= ~CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED; ret = smb347_write(smb, CFG_SYSOK, ret); if (ret < 0) return ret; } if (smb->pdata->soft_temp_limit_compensation != SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) { val = smb->pdata->soft_temp_limit_compensation & 0x3; ret = smb347_read(smb, CFG_THERM); if (ret < 0) return ret; ret &= ~CFG_THERM_SOFT_HOT_COMPENSATION_MASK; ret |= val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT; ret &= ~CFG_THERM_SOFT_COLD_COMPENSATION_MASK; ret |= val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT; ret = smb347_write(smb, CFG_THERM, ret); if (ret < 0) return ret; } if (smb->pdata->charge_current_compensation) { val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl), smb->pdata->charge_current_compensation); if (val < 0) return val; ret = smb347_read(smb, CFG_OTG); if (ret < 0) return ret; ret &= ~CFG_OTG_CC_COMPENSATION_MASK; ret |= (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT; ret = smb347_write(smb, CFG_OTG, ret); if (ret < 0) return ret; } return ret; }
static int smb347_set_temp_limits(struct smb347_charger *smb) { bool enable_therm_monitor = false; int ret, val; if (smb->pdata->chip_temp_threshold) { val = smb->pdata->chip_temp_threshold; val = clamp_val(val, 100, 130) - 100; val /= 10; ret = smb347_read(smb, CFG_OTG); if (ret < 0) return ret; ret &= ~CFG_OTG_TEMP_THRESHOLD_MASK; ret |= val << CFG_OTG_TEMP_THRESHOLD_SHIFT; ret = smb347_write(smb, CFG_OTG, ret); if (ret < 0) return ret; } ret = smb347_read(smb, CFG_TEMP_LIMIT); if (ret < 0) return ret; if (smb->pdata->soft_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->soft_cold_temp_limit; val = clamp_val(val, 0, 15); val /= 5; val = ~val & 0x3; ret &= ~CFG_TEMP_LIMIT_SOFT_COLD_MASK; ret |= val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT; enable_therm_monitor = true; } if (smb->pdata->soft_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->soft_hot_temp_limit; val = clamp_val(val, 40, 55) - 40; val /= 5; ret &= ~CFG_TEMP_LIMIT_SOFT_HOT_MASK; ret |= val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT; enable_therm_monitor = true; } if (smb->pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->hard_cold_temp_limit; val = clamp_val(val, -5, 10) + 5; val /= 5; val = ~val & 0x3; ret &= ~CFG_TEMP_LIMIT_HARD_COLD_MASK; ret |= val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT; enable_therm_monitor = true; } if (smb->pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) { val = smb->pdata->hard_hot_temp_limit; val = clamp_val(val, 50, 65) - 50; val /= 5; ret &= ~CFG_TEMP_LIMIT_HARD_HOT_MASK; ret |= val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT; enable_therm_monitor = true; } ret = smb347_write(smb, CFG_TEMP_LIMIT, ret); if (ret < 0) return ret; if (enable_therm_monitor) { ret = smb347_read(smb, CFG_THERM); if (ret < 0) return ret; ret &= ~CFG_THERM_MONITOR_DISABLED; ret = smb347_write(smb, CFG_THERM, ret); if (ret < 0) return ret; } if (smb->pdata->suspend_on_hard_temp_limit) { ret = smb347_read(smb, CFG_SYSOK); if (ret < 0) return ret; ret &= ~CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED; ret = smb347_write(smb, CFG_SYSOK, ret); if (ret < 0) return ret; } if (smb->pdata->soft_temp_limit_compensation != SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) { val = smb->pdata->soft_temp_limit_compensation & 0x3; ret = smb347_read(smb, CFG_THERM); if (ret < 0) return ret; ret &= ~CFG_THERM_SOFT_HOT_COMPENSATION_MASK; ret |= val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT; ret &= ~CFG_THERM_SOFT_COLD_COMPENSATION_MASK; ret |= val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT; ret = smb347_write(smb, CFG_THERM, ret); if (ret < 0) return ret; } if (smb->pdata->charge_current_compensation) { val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl), smb->pdata->charge_current_compensation); if (val < 0) return val; ret = smb347_read(smb, CFG_OTG); if (ret < 0) return ret; ret &= ~CFG_OTG_CC_COMPENSATION_MASK; ret |= (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT; ret = smb347_write(smb, CFG_OTG, ret); if (ret < 0) return ret; } return ret; }