diff options
Diffstat (limited to 'drivers/power/supply/cpcap-charger.c')
-rw-r--r-- | drivers/power/supply/cpcap-charger.c | 89 |
1 files changed, 54 insertions, 35 deletions
diff --git a/drivers/power/supply/cpcap-charger.c b/drivers/power/supply/cpcap-charger.c index 26a2dc7ac9a2..11a07633de6c 100644 --- a/drivers/power/supply/cpcap-charger.c +++ b/drivers/power/supply/cpcap-charger.c @@ -38,20 +38,27 @@ #include <linux/iio/consumer.h> #include <linux/mfd/motorola-cpcap.h> -/* CPCAP_REG_CRM register bits */ +/* + * CPCAP_REG_CRM register bits. For documentation of somewhat similar hardware, + * see NXP "MC13783 Power Management and Audio Circuit Users's Guide" + * MC13783UG.pdf chapter "8.5 Battery Interface Register Summary". The registers + * and values for CPCAP are different, but some of the internal components seem + * similar. Also see the Motorola Linux kernel cpcap-regbits.h. CPCAP_REG_CHRGR_1 + * bits that seem to describe the CRM register. + */ #define CPCAP_REG_CRM_UNUSED_641_15 BIT(15) /* 641 = register number */ #define CPCAP_REG_CRM_UNUSED_641_14 BIT(14) /* 641 = register number */ -#define CPCAP_REG_CRM_CHRG_LED_EN BIT(13) -#define CPCAP_REG_CRM_RVRSMODE BIT(12) -#define CPCAP_REG_CRM_ICHRG_TR1 BIT(11) +#define CPCAP_REG_CRM_CHRG_LED_EN BIT(13) /* Charger LED */ +#define CPCAP_REG_CRM_RVRSMODE BIT(12) /* USB VBUS output enable */ +#define CPCAP_REG_CRM_ICHRG_TR1 BIT(11) /* Trickle charge current */ #define CPCAP_REG_CRM_ICHRG_TR0 BIT(10) -#define CPCAP_REG_CRM_FET_OVRD BIT(9) -#define CPCAP_REG_CRM_FET_CTRL BIT(8) -#define CPCAP_REG_CRM_VCHRG3 BIT(7) +#define CPCAP_REG_CRM_FET_OVRD BIT(9) /* 0 = hardware, 1 = FET_CTRL */ +#define CPCAP_REG_CRM_FET_CTRL BIT(8) /* BPFET 1 if FET_OVRD set */ +#define CPCAP_REG_CRM_VCHRG3 BIT(7) /* Charge voltage bits */ #define CPCAP_REG_CRM_VCHRG2 BIT(6) #define CPCAP_REG_CRM_VCHRG1 BIT(5) #define CPCAP_REG_CRM_VCHRG0 BIT(4) -#define CPCAP_REG_CRM_ICHRG3 BIT(3) +#define CPCAP_REG_CRM_ICHRG3 BIT(3) /* Charge current bits */ #define CPCAP_REG_CRM_ICHRG2 BIT(2) #define CPCAP_REG_CRM_ICHRG1 BIT(1) #define CPCAP_REG_CRM_ICHRG0 BIT(0) @@ -63,42 +70,50 @@ #define CPCAP_REG_CRM_TR_0A48 CPCAP_REG_CRM_TR(0x2) #define CPCAP_REG_CRM_TR_0A72 CPCAP_REG_CRM_TR(0x4) -/* CPCAP_REG_CRM charge voltages */ +/* + * CPCAP_REG_CRM charge voltages based on the ADC channel 1 values. + * Note that these register bits don't match MC13783UG.pdf VCHRG + * register bits. + */ #define CPCAP_REG_CRM_VCHRG(val) (((val) & 0xf) << 4) #define CPCAP_REG_CRM_VCHRG_3V80 CPCAP_REG_CRM_VCHRG(0x0) #define CPCAP_REG_CRM_VCHRG_4V10 CPCAP_REG_CRM_VCHRG(0x1) -#define CPCAP_REG_CRM_VCHRG_4V15 CPCAP_REG_CRM_VCHRG(0x2) -#define CPCAP_REG_CRM_VCHRG_4V20 CPCAP_REG_CRM_VCHRG(0x3) -#define CPCAP_REG_CRM_VCHRG_4V22 CPCAP_REG_CRM_VCHRG(0x4) -#define CPCAP_REG_CRM_VCHRG_4V24 CPCAP_REG_CRM_VCHRG(0x5) -#define CPCAP_REG_CRM_VCHRG_4V26 CPCAP_REG_CRM_VCHRG(0x6) -#define CPCAP_REG_CRM_VCHRG_4V28 CPCAP_REG_CRM_VCHRG(0x7) -#define CPCAP_REG_CRM_VCHRG_4V30 CPCAP_REG_CRM_VCHRG(0x8) -#define CPCAP_REG_CRM_VCHRG_4V32 CPCAP_REG_CRM_VCHRG(0x9) -#define CPCAP_REG_CRM_VCHRG_4V34 CPCAP_REG_CRM_VCHRG(0xa) +#define CPCAP_REG_CRM_VCHRG_4V12 CPCAP_REG_CRM_VCHRG(0x2) +#define CPCAP_REG_CRM_VCHRG_4V15 CPCAP_REG_CRM_VCHRG(0x3) +#define CPCAP_REG_CRM_VCHRG_4V17 CPCAP_REG_CRM_VCHRG(0x4) +#define CPCAP_REG_CRM_VCHRG_4V20 CPCAP_REG_CRM_VCHRG(0x5) +#define CPCAP_REG_CRM_VCHRG_4V23 CPCAP_REG_CRM_VCHRG(0x6) +#define CPCAP_REG_CRM_VCHRG_4V25 CPCAP_REG_CRM_VCHRG(0x7) +#define CPCAP_REG_CRM_VCHRG_4V27 CPCAP_REG_CRM_VCHRG(0x8) +#define CPCAP_REG_CRM_VCHRG_4V30 CPCAP_REG_CRM_VCHRG(0x9) +#define CPCAP_REG_CRM_VCHRG_4V33 CPCAP_REG_CRM_VCHRG(0xa) #define CPCAP_REG_CRM_VCHRG_4V35 CPCAP_REG_CRM_VCHRG(0xb) #define CPCAP_REG_CRM_VCHRG_4V38 CPCAP_REG_CRM_VCHRG(0xc) #define CPCAP_REG_CRM_VCHRG_4V40 CPCAP_REG_CRM_VCHRG(0xd) #define CPCAP_REG_CRM_VCHRG_4V42 CPCAP_REG_CRM_VCHRG(0xe) #define CPCAP_REG_CRM_VCHRG_4V44 CPCAP_REG_CRM_VCHRG(0xf) -/* CPCAP_REG_CRM charge currents */ +/* + * CPCAP_REG_CRM charge currents. These seem to match MC13783UG.pdf + * values in "Table 8-3. Charge Path Regulator Current Limit + * Characteristics" for the nominal values. + */ #define CPCAP_REG_CRM_ICHRG(val) (((val) & 0xf) << 0) #define CPCAP_REG_CRM_ICHRG_0A000 CPCAP_REG_CRM_ICHRG(0x0) #define CPCAP_REG_CRM_ICHRG_0A070 CPCAP_REG_CRM_ICHRG(0x1) -#define CPCAP_REG_CRM_ICHRG_0A176 CPCAP_REG_CRM_ICHRG(0x2) -#define CPCAP_REG_CRM_ICHRG_0A264 CPCAP_REG_CRM_ICHRG(0x3) -#define CPCAP_REG_CRM_ICHRG_0A352 CPCAP_REG_CRM_ICHRG(0x4) -#define CPCAP_REG_CRM_ICHRG_0A440 CPCAP_REG_CRM_ICHRG(0x5) -#define CPCAP_REG_CRM_ICHRG_0A528 CPCAP_REG_CRM_ICHRG(0x6) -#define CPCAP_REG_CRM_ICHRG_0A616 CPCAP_REG_CRM_ICHRG(0x7) -#define CPCAP_REG_CRM_ICHRG_0A704 CPCAP_REG_CRM_ICHRG(0x8) -#define CPCAP_REG_CRM_ICHRG_0A792 CPCAP_REG_CRM_ICHRG(0x9) -#define CPCAP_REG_CRM_ICHRG_0A880 CPCAP_REG_CRM_ICHRG(0xa) -#define CPCAP_REG_CRM_ICHRG_0A968 CPCAP_REG_CRM_ICHRG(0xb) -#define CPCAP_REG_CRM_ICHRG_1A056 CPCAP_REG_CRM_ICHRG(0xc) -#define CPCAP_REG_CRM_ICHRG_1A144 CPCAP_REG_CRM_ICHRG(0xd) -#define CPCAP_REG_CRM_ICHRG_1A584 CPCAP_REG_CRM_ICHRG(0xe) +#define CPCAP_REG_CRM_ICHRG_0A177 CPCAP_REG_CRM_ICHRG(0x2) +#define CPCAP_REG_CRM_ICHRG_0A266 CPCAP_REG_CRM_ICHRG(0x3) +#define CPCAP_REG_CRM_ICHRG_0A355 CPCAP_REG_CRM_ICHRG(0x4) +#define CPCAP_REG_CRM_ICHRG_0A443 CPCAP_REG_CRM_ICHRG(0x5) +#define CPCAP_REG_CRM_ICHRG_0A532 CPCAP_REG_CRM_ICHRG(0x6) +#define CPCAP_REG_CRM_ICHRG_0A621 CPCAP_REG_CRM_ICHRG(0x7) +#define CPCAP_REG_CRM_ICHRG_0A709 CPCAP_REG_CRM_ICHRG(0x8) +#define CPCAP_REG_CRM_ICHRG_0A798 CPCAP_REG_CRM_ICHRG(0x9) +#define CPCAP_REG_CRM_ICHRG_0A886 CPCAP_REG_CRM_ICHRG(0xa) +#define CPCAP_REG_CRM_ICHRG_0A975 CPCAP_REG_CRM_ICHRG(0xb) +#define CPCAP_REG_CRM_ICHRG_1A064 CPCAP_REG_CRM_ICHRG(0xc) +#define CPCAP_REG_CRM_ICHRG_1A152 CPCAP_REG_CRM_ICHRG(0xd) +#define CPCAP_REG_CRM_ICHRG_1A596 CPCAP_REG_CRM_ICHRG(0xe) #define CPCAP_REG_CRM_ICHRG_NO_LIMIT CPCAP_REG_CRM_ICHRG(0xf) enum { @@ -428,9 +443,9 @@ static void cpcap_usb_detect(struct work_struct *work) int max_current; if (cpcap_charger_battery_found(ddata)) - max_current = CPCAP_REG_CRM_ICHRG_1A584; + max_current = CPCAP_REG_CRM_ICHRG_1A596; else - max_current = CPCAP_REG_CRM_ICHRG_0A528; + max_current = CPCAP_REG_CRM_ICHRG_0A532; error = cpcap_charger_set_state(ddata, CPCAP_REG_CRM_VCHRG_4V35, @@ -586,6 +601,7 @@ static int cpcap_charger_probe(struct platform_device *pdev) { struct cpcap_charger_ddata *ddata; const struct of_device_id *of_id; + struct power_supply_config psy_cfg = {}; int error; of_id = of_match_device(of_match_ptr(cpcap_charger_id_table), @@ -614,9 +630,12 @@ static int cpcap_charger_probe(struct platform_device *pdev) atomic_set(&ddata->active, 1); + psy_cfg.of_node = pdev->dev.of_node; + psy_cfg.drv_data = ddata; + ddata->usb = devm_power_supply_register(ddata->dev, &cpcap_charger_usb_desc, - NULL); + &psy_cfg); if (IS_ERR(ddata->usb)) { error = PTR_ERR(ddata->usb); dev_err(ddata->dev, "failed to register USB charger: %i\n", |