switch (attach) { case MT6370_ATTACH_STAT_DETACH:
usb_stat = 0; break; case MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12:
ret = mt6370_chg_field_set(priv, F_USBCHGEN, attach); if (ret)
dev_err(priv->dev, "Failed to enable USB CHG EN\n"); goto bc12_work_func_out; case MT6370_ATTACH_STAT_ATTACH_BC12_DONE:
ret = mt6370_chg_field_get(priv, F_USB_STAT, &usb_stat); if (ret) {
dev_err(priv->dev, "Failed to get USB status\n"); goto bc12_work_func_out;
} break; default:
dev_err(priv->dev, "Invalid attach state\n"); goto bc12_work_func_out;
}
rpt_psy = true;
switch (usb_stat) { case MT6370_USB_STAT_SDP: case MT6370_USB_STAT_SDP_NSTD:
priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP; break; case MT6370_USB_STAT_DCP:
priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_DCP; break; case MT6370_USB_STAT_CDP:
priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_CDP; break; case MT6370_USB_STAT_NO_VBUS: case MT6370_USB_STAT_VBUS_FLOW_IS_UNDER_GOING: default:
priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_UNKNOWN; break;
}
staticint mt6370_chg_toggle_cfo(struct mt6370_priv *priv)
{ int ret; unsignedint fl_strobe;
/* check if flash led in strobe mode */
ret = mt6370_chg_field_get(priv, F_FL_STROBE, &fl_strobe); if (ret) {
dev_err(priv->dev, "Failed to get FL_STROBE_EN\n"); return ret;
}
if (fl_strobe) {
dev_err(priv->dev, "Flash led is still in strobe mode\n"); return -EINVAL;
}
/* cfo off */
ret = mt6370_chg_field_set(priv, F_CFO_EN, 0); if (ret) {
dev_err(priv->dev, "Failed to disable CFO_EN\n"); return ret;
}
/* cfo on */
ret = mt6370_chg_field_set(priv, F_CFO_EN, 1); if (ret)
dev_err(priv->dev, "Failed to enable CFO_EN\n");
return ret;
}
staticint mt6370_chg_read_adc_chan(struct mt6370_priv *priv, unsignedint chan, int *val)
{ int ret;
if (chan >= MT6370_ADC_CHAN_MAX) return -EINVAL;
ret = iio_read_channel_processed(&priv->iio_adcs[chan], val); if (ret)
dev_err(priv->dev, "Failed to read ADC\n");
staticvoid mt6370_chg_pwr_rdy_check(struct mt6370_priv *priv)
{ int ret; unsignedint opposite_pwr_rdy, otg_en; union power_supply_propval val;
/* Check in OTG mode or not */
ret = mt6370_chg_field_get(priv, F_BOOST_STAT, &otg_en); if (ret) {
dev_err(priv->dev, "Failed to get OTG state\n"); return;
}
if (otg_en) return;
ret = mt6370_chg_field_get(priv, F_UVP_D_STAT, &opposite_pwr_rdy); if (ret) {
dev_err(priv->dev, "Failed to get opposite power ready state\n"); return;
}
staticint mt6370_chg_get_status(struct mt6370_priv *priv, union power_supply_propval *val)
{ int ret; unsignedint chg_stat; union power_supply_propval online;
ret = power_supply_get_property(priv->psy, POWER_SUPPLY_PROP_ONLINE,
&online); if (ret) {
dev_err(priv->dev, "Failed to get online status\n"); return ret;
}
if (!online.intval) {
val->intval = POWER_SUPPLY_STATUS_DISCHARGING; return 0;
}
ret = mt6370_chg_field_get(priv, F_CHG_STAT, &chg_stat); if (ret) return ret;
switch (chg_stat) { case MT6370_CHG_STAT_READY: case MT6370_CHG_STAT_FAULT:
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; return ret; case MT6370_CHG_STAT_CHARGE_IN_PROGRESS:
val->intval = POWER_SUPPLY_STATUS_CHARGING; return ret; case MT6370_CHG_STAT_DONE:
val->intval = POWER_SUPPLY_STATUS_FULL; return ret; default:
val->intval = POWER_SUPPLY_STATUS_UNKNOWN; return ret;
}
}
staticint mt6370_chg_get_charge_type(struct mt6370_priv *priv, union power_supply_propval *val)
{ int type, ret; unsignedint chg_stat, vbat_lvl;
ret = mt6370_chg_field_get(priv, F_CHG_STAT, &chg_stat); if (ret) return ret;
ret = mt6370_chg_field_get(priv, F_VBAT_LVL, &vbat_lvl); if (ret) return ret;
switch (chg_stat) { case MT6370_CHG_STAT_CHARGE_IN_PROGRESS: if (vbat_lvl)
type = POWER_SUPPLY_CHARGE_TYPE_FAST; else
type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; break; case MT6370_CHG_STAT_READY: case MT6370_CHG_STAT_DONE: case MT6370_CHG_STAT_FAULT: default:
type = POWER_SUPPLY_CHARGE_TYPE_NONE; break;
}
switch (psp) { case POWER_SUPPLY_PROP_ONLINE: return mt6370_chg_set_online(priv, val); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: return mt6370_chg_field_set(priv, F_ICHG, val->intval); case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: return mt6370_chg_field_set(priv, F_VOREG, val->intval); case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: return mt6370_chg_field_set(priv, F_IAICR, val->intval); case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: return mt6370_chg_field_set(priv, F_VMIVR, val->intval); case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: return mt6370_chg_field_set(priv, F_IPREC, val->intval); case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: return mt6370_chg_field_set(priv, F_IEOC, val->intval); default: return -EINVAL;
}
}
staticint mt6370_chg_property_is_writeable(struct power_supply *psy, enum power_supply_property psp)
{ switch (psp) { case POWER_SUPPLY_PROP_ONLINE: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE: case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: return 1; default: return 0;
}
}
for (i = 0; i < F_MAX; i++) {
priv->rmap_fields[i] = devm_regmap_field_alloc(priv->dev,
priv->regmap,
fds[i].field); if (IS_ERR(priv->rmap_fields[i])) return dev_err_probe(priv->dev,
PTR_ERR(priv->rmap_fields[i]), "Failed to allocate regmapfield[%s]\n",
fds[i].name);
}
return 0;
}
staticint mt6370_chg_init_setting(struct mt6370_priv *priv)
{ int ret;
/* Disable usb_chg_en */
ret = mt6370_chg_field_set(priv, F_USBCHGEN, 0); if (ret) {
dev_err(priv->dev, "Failed to disable usb_chg_en\n"); return ret;
}
/* Disable input current limit */
ret = mt6370_chg_field_set(priv, F_ILIM_EN, 0); if (ret) {
dev_err(priv->dev, "Failed to disable input current limit\n"); return ret;
}
/* ICHG/IEOC Workaround, ICHG can not be set less than 900mA */
ret = mt6370_chg_field_set(priv, F_ICHG, 900000); if (ret) {
dev_err(priv->dev, "Failed to set ICHG to 900mA"); return ret;
}
/* Change input current limit selection to using IAICR results */
ret = mt6370_chg_field_set(priv, F_IINLMTSEL, 2); if (ret) {
dev_err(priv->dev, "Failed to set IINLMTSEL\n"); return ret;
}
/* Check in OTG mode or not */
ret = mt6370_chg_field_get(priv, F_BOOST_STAT, &otg_en); if (ret) {
dev_err(priv->dev, "Failed to get OTG state\n"); return IRQ_NONE;
}
for (i = 0; i < ARRAY_SIZE(mt6370_chg_irqs); i++) {
ret = platform_get_irq_byname(to_platform_device(priv->dev),
mt6370_chg_irqs[i].name); if (ret < 0) return ret;
priv->irq_nums[i] = ret;
ret = devm_request_threaded_irq(priv->dev, ret, NULL,
mt6370_chg_irqs[i].handler,
IRQF_TRIGGER_FALLING,
dev_name(priv->dev), priv); if (ret) return dev_err_probe(priv->dev, ret, "Failed to request irq %s\n",
mt6370_chg_irqs[i].name);
}
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM;
priv->dev = &pdev->dev;
priv->regmap = dev_get_regmap(pdev->dev.parent, NULL); if (!priv->regmap) return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");
ret = mt6370_chg_init_rmap_fields(priv); if (ret) return dev_err_probe(dev, ret, "Failed to init regmap fields\n");
platform_set_drvdata(pdev, priv);
priv->iio_adcs = devm_iio_channel_get_all(priv->dev); if (IS_ERR(priv->iio_adcs)) return dev_err_probe(dev, PTR_ERR(priv->iio_adcs), "Failed to get iio adc\n");
ret = mt6370_chg_init_otg_regulator(priv); if (ret) return dev_err_probe(dev, ret, "Failed to init OTG regulator\n");
ret = mt6370_chg_init_psy(priv); if (ret) return dev_err_probe(dev, ret, "Failed to init psy\n");
mutex_init(&priv->attach_lock);
ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_attach_lock,
&priv->attach_lock); if (ret) return dev_err_probe(dev, ret, "Failed to init attach lock\n");
priv->attach = MT6370_ATTACH_STAT_DETACH;
priv->wq = create_singlethread_workqueue(dev_name(priv->dev)); if (!priv->wq) return dev_err_probe(dev, -ENOMEM, "Failed to create workqueue\n");
ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_wq, priv->wq); if (ret) return dev_err_probe(dev, ret, "Failed to init wq\n");
ret = devm_work_autocancel(dev, &priv->bc12_work, mt6370_chg_bc12_work_func); if (ret) return dev_err_probe(dev, ret, "Failed to init bc12 work\n");
ret = devm_delayed_work_autocancel(dev, &priv->mivr_dwork, mt6370_chg_mivr_dwork_func); if (ret) return dev_err_probe(dev, ret, "Failed to init mivr delayed work\n");
ret = mt6370_chg_init_setting(priv); if (ret) return dev_err_probe(dev, ret, "Failed to init mt6370 charger setting\n");
ret = mt6370_chg_init_irq(priv); if (ret) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.