Immutable branch between arm and power-supply for cpcap-charger
This immutable branch contains CPCAP charger changes, which touch ARM and power-supply subsystem. Signed-off-by: Sebastian Reichel <sre@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAl2splkACgkQ2O7X88g7 +pp4WQ/9FE28GAkDDFajfVugAjPm5RcIIhHv0Hw7OXPxolKFNB24xbDe6AT1V7sn NLzwnHp9Ra8xxwXY4FsbG1i0KLzJIimPrzhLbYf3NkIZ+s/z/7GdzY5mKPImgWIy 7cP/2+Zo3tSWFK4njxgecPUoi8fkAZKnEfiJDn9TgQ6aZ6ZN6koRAx33ZkbDyXYl CWXFHmxnVCoskyzmPQhWJW8D96lmOgJEt2Dpao/Vn2QhQFY2m+VQjkq73DNTGlDM 6yT1hf+M8jTWMUQV6CEJfc6g6D0g/a6TCJ6hXihdiA0dF/ZhqACImpQxh5hPbZ6R iuR1ojqM4hv/mR9EoLTJWIvL5zEwmT/3UCXjbDjrSFJsYFe+9h1x9PissNcgui2j o1r/GDwKgQTQ54Kve/AS9Tjv1p6dqTzJmWCqE5fPIqZSc7WpQ9n0TZXuUXY/HQfy 7c8kPbgPeoI9QbR8KdeajaZD7kiFecQEpsGp15aYXdnAYkFtxcWYZIZgrwQ4tm58 I5hDf53ABsrl1ALJuC+FUX1Mjz4C7hyWtxuS1udBAYgt+bEjx3LbsSPegcjTXad2 F2Ue+9SpHdZMD25i7CCBch0eA6Ko+3YAJkzDaCtK3t4wRTEJneCxxwXOMc564ktf VWeK2F5ASHMeft8Yml7oOu/4SkRo6lJ4/Bwcpz75Cf0la6WWUSE= =Nbmd -----END PGP SIGNATURE----- Merge tag 'psy-cpcap-charge-volt-limit-signed' into psy-next Immutable branch between arm and power-supply for cpcap-charger This immutable branch contains CPCAP charger changes, which touch ARM and power-supply subsystem. Signed-off-by: Sebastian Reichel <sre@kernel.org>
This commit is contained in:
commit
8bc8fc088b
@ -5,7 +5,8 @@ Required properties:
|
||||
- interrupts: Interrupt specifier for each name in interrupt-names
|
||||
- interrupt-names: Should contain the following entries:
|
||||
"chrg_det", "rvrs_chrg", "chrg_se1b", "se0conn",
|
||||
"rvrs_mode", "chrgcurr1", "vbusvld", "battdetb"
|
||||
"rvrs_mode", "chrgcurr2", "chrgcurr1", "vbusvld",
|
||||
"battdetb"
|
||||
- io-channels: IIO ADC channel specifier for each name in io-channel-names
|
||||
- io-channel-names: Should contain the following entries:
|
||||
"battdetb", "battp", "vbus", "chg_isense", "batti"
|
||||
@ -21,11 +22,13 @@ cpcap_charger: charger {
|
||||
compatible = "motorola,mapphone-cpcap-charger";
|
||||
interrupts-extended = <
|
||||
&cpcap 13 0 &cpcap 12 0 &cpcap 29 0 &cpcap 28 0
|
||||
&cpcap 22 0 &cpcap 20 0 &cpcap 19 0 &cpcap 54 0
|
||||
&cpcap 22 0 &cpcap 21 0 &cpcap 20 0 &cpcap 19 0
|
||||
&cpcap 54 0
|
||||
>;
|
||||
interrupt-names =
|
||||
"chrg_det", "rvrs_chrg", "chrg_se1b", "se0conn",
|
||||
"rvrs_mode", "chrgcurr1", "vbusvld", "battdetb";
|
||||
"rvrs_mode", "chrgcurr2", "chrgcurr1", "vbusvld",
|
||||
"battdetb";
|
||||
mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW
|
||||
&gpio3 23 GPIO_ACTIVE_LOW>;
|
||||
io-channels = <&cpcap_adc 0 &cpcap_adc 1
|
||||
|
@ -43,11 +43,13 @@
|
||||
compatible = "motorola,mapphone-cpcap-charger";
|
||||
interrupts-extended = <
|
||||
&cpcap 13 0 &cpcap 12 0 &cpcap 29 0 &cpcap 28 0
|
||||
&cpcap 22 0 &cpcap 20 0 &cpcap 19 0 &cpcap 54 0
|
||||
&cpcap 22 0 &cpcap 21 0 &cpcap 20 0 &cpcap 19 0
|
||||
&cpcap 54 0
|
||||
>;
|
||||
interrupt-names =
|
||||
"chrg_det", "rvrs_chrg", "chrg_se1b", "se0conn",
|
||||
"rvrs_mode", "chrgcurr1", "vbusvld", "battdetb";
|
||||
"rvrs_mode", "chrgcurr2", "chrgcurr1", "vbusvld",
|
||||
"battdetb";
|
||||
mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW
|
||||
&gpio3 23 GPIO_ACTIVE_LOW>;
|
||||
io-channels = <&cpcap_adc 0 &cpcap_adc 1
|
||||
|
@ -120,6 +120,13 @@ enum {
|
||||
CPCAP_CHARGER_IIO_NR,
|
||||
};
|
||||
|
||||
enum {
|
||||
CPCAP_CHARGER_DISCONNECTED,
|
||||
CPCAP_CHARGER_DETECTING,
|
||||
CPCAP_CHARGER_CHARGING,
|
||||
CPCAP_CHARGER_DONE,
|
||||
};
|
||||
|
||||
struct cpcap_charger_ddata {
|
||||
struct device *dev;
|
||||
struct regmap *reg;
|
||||
@ -138,6 +145,8 @@ struct cpcap_charger_ddata {
|
||||
atomic_t active;
|
||||
|
||||
int status;
|
||||
int state;
|
||||
int voltage;
|
||||
};
|
||||
|
||||
struct cpcap_interrupt_desc {
|
||||
@ -153,6 +162,7 @@ struct cpcap_charger_ints_state {
|
||||
|
||||
bool chrg_se1b;
|
||||
bool rvrs_mode;
|
||||
bool chrgcurr2;
|
||||
bool chrgcurr1;
|
||||
bool vbusvld;
|
||||
|
||||
@ -422,6 +432,7 @@ static int cpcap_charger_get_ints_state(struct cpcap_charger_ddata *ddata,
|
||||
|
||||
s->chrg_se1b = val & BIT(13);
|
||||
s->rvrs_mode = val & BIT(6);
|
||||
s->chrgcurr2 = val & BIT(5);
|
||||
s->chrgcurr1 = val & BIT(4);
|
||||
s->vbusvld = val & BIT(3);
|
||||
|
||||
@ -434,6 +445,79 @@ static int cpcap_charger_get_ints_state(struct cpcap_charger_ddata *ddata,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpcap_charger_update_state(struct cpcap_charger_ddata *ddata,
|
||||
int state)
|
||||
{
|
||||
const char *status;
|
||||
|
||||
if (state > CPCAP_CHARGER_DONE) {
|
||||
dev_warn(ddata->dev, "unknown state: %i\n", state);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ddata->state = state;
|
||||
|
||||
switch (state) {
|
||||
case CPCAP_CHARGER_DISCONNECTED:
|
||||
status = "DISCONNECTED";
|
||||
break;
|
||||
case CPCAP_CHARGER_DETECTING:
|
||||
status = "DETECTING";
|
||||
break;
|
||||
case CPCAP_CHARGER_CHARGING:
|
||||
status = "CHARGING";
|
||||
break;
|
||||
case CPCAP_CHARGER_DONE:
|
||||
status = "DONE";
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
dev_dbg(ddata->dev, "state: %s\n", status);
|
||||
}
|
||||
|
||||
int cpcap_charger_voltage_to_regval(int voltage)
|
||||
{
|
||||
int offset;
|
||||
|
||||
switch (voltage) {
|
||||
case 0 ... 4100000 - 1:
|
||||
return 0;
|
||||
case 4100000 ... 4200000 - 1:
|
||||
offset = 1;
|
||||
break;
|
||||
case 4200000 ... 4300000 - 1:
|
||||
offset = 0;
|
||||
break;
|
||||
case 4300000 ... 4380000 - 1:
|
||||
offset = -1;
|
||||
break;
|
||||
case 4380000 ... 4440000:
|
||||
offset = -2;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((voltage - 4100000) / 20000) + offset;
|
||||
}
|
||||
|
||||
static void cpcap_charger_disconnect(struct cpcap_charger_ddata *ddata,
|
||||
int state, unsigned long delay)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = cpcap_charger_set_state(ddata, 0, 0, 0);
|
||||
if (error)
|
||||
return;
|
||||
|
||||
cpcap_charger_update_state(ddata, state);
|
||||
power_supply_changed(ddata->usb);
|
||||
schedule_delayed_work(&ddata->detect_work, delay);
|
||||
}
|
||||
|
||||
static void cpcap_usb_detect(struct work_struct *work)
|
||||
{
|
||||
struct cpcap_charger_ddata *ddata;
|
||||
@ -447,24 +531,67 @@ static void cpcap_usb_detect(struct work_struct *work)
|
||||
if (error)
|
||||
return;
|
||||
|
||||
/* Just init the state if a charger is connected with no chrg_det set */
|
||||
if (!s.chrg_det && s.chrgcurr1 && s.vbusvld) {
|
||||
cpcap_charger_update_state(ddata, CPCAP_CHARGER_DETECTING);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* If battery voltage is higher than charge voltage, it may have been
|
||||
* charged to 4.35V by Android. Try again in 10 minutes.
|
||||
*/
|
||||
if (cpcap_charger_get_charge_voltage(ddata) > ddata->voltage) {
|
||||
cpcap_charger_disconnect(ddata, CPCAP_CHARGER_DETECTING,
|
||||
HZ * 60 * 10);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Throttle chrgcurr2 interrupt for charger done and retry */
|
||||
switch (ddata->state) {
|
||||
case CPCAP_CHARGER_CHARGING:
|
||||
if (s.chrgcurr2)
|
||||
break;
|
||||
if (s.chrgcurr1 && s.vbusvld) {
|
||||
cpcap_charger_disconnect(ddata, CPCAP_CHARGER_DONE,
|
||||
HZ * 5);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case CPCAP_CHARGER_DONE:
|
||||
if (!s.chrgcurr2)
|
||||
break;
|
||||
cpcap_charger_disconnect(ddata, CPCAP_CHARGER_DETECTING,
|
||||
HZ * 5);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) &&
|
||||
s.chrgcurr1) {
|
||||
int max_current;
|
||||
int vchrg;
|
||||
|
||||
if (cpcap_charger_battery_found(ddata))
|
||||
max_current = CPCAP_REG_CRM_ICHRG_1A596;
|
||||
else
|
||||
max_current = CPCAP_REG_CRM_ICHRG_0A532;
|
||||
|
||||
vchrg = cpcap_charger_voltage_to_regval(ddata->voltage);
|
||||
error = cpcap_charger_set_state(ddata,
|
||||
CPCAP_REG_CRM_VCHRG_4V35,
|
||||
CPCAP_REG_CRM_VCHRG(vchrg),
|
||||
max_current, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
cpcap_charger_update_state(ddata, CPCAP_CHARGER_CHARGING);
|
||||
} else {
|
||||
error = cpcap_charger_set_state(ddata, 0, 0, 0);
|
||||
if (error)
|
||||
goto out_err;
|
||||
cpcap_charger_update_state(ddata, CPCAP_CHARGER_DISCONNECTED);
|
||||
}
|
||||
|
||||
power_supply_changed(ddata->usb);
|
||||
@ -524,7 +651,7 @@ static const char * const cpcap_charger_irqs[] = {
|
||||
"chrg_det", "rvrs_chrg",
|
||||
|
||||
/* REG_INT1 */
|
||||
"chrg_se1b", "se0conn", "rvrs_mode", "chrgcurr1", "vbusvld",
|
||||
"chrg_se1b", "se0conn", "rvrs_mode", "chrgcurr2", "chrgcurr1", "vbusvld",
|
||||
|
||||
/* REG_INT_3 */
|
||||
"battdetb",
|
||||
@ -625,6 +752,7 @@ static int cpcap_charger_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
|
||||
ddata->dev = &pdev->dev;
|
||||
ddata->voltage = 4200000;
|
||||
|
||||
ddata->reg = dev_get_regmap(ddata->dev->parent, NULL);
|
||||
if (!ddata->reg)
|
||||
|
Loading…
Reference in New Issue
Block a user