[Gta04-owner] [PATCH] twl4030_charger: add software controlled linear charging mode.

Andreas Kemnade andreas at kemnade.info
Thu Sep 26 20:09:32 CEST 2013


Hi,


On Thu, 26 Sep 2013 15:19:40 +0200
"Dr. H. Nikolaus Schaller" <hns at goldelico.com> wrote:

> Hi Ben,
> thanks for the patch. I have applied it and now the /sys/.../lin file is back again.
> 
> One question (maybe to Andreas): "on" sets the variable do_lin=1 and "auto" resets it if it was on. But "off" does not set it to 0. Is this intended behaviour?
>
yes, that is intended behaviour:
off= manual off (and no auto on, prevented by do_lin still =0 )
auto=automatic charge mode
on = manual on 

btw: it is possible to keep the gta04 in suspend mode with do_lin=on when power supply goes on and off. Tested on my bike on the very hilly and windy roads around the North Cape.



> ---
> > drivers/power/twl4030_charger.c | 100 ++++++++++++++++++++++++++++++++++++----
> > 1 file changed, 92 insertions(+), 8 deletions(-)
> > 
> > diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
> > index e9de746..33be55d 100644
> > --- a/drivers/power/twl4030_charger.c
> > +++ b/drivers/power/twl4030_charger.c
> > @@ -24,6 +24,8 @@
> > #include <linux/usb/otg.h>
> > #include <linux/regulator/machine.h>
> > 
> > +#define TWL4030_BCIMDEN		0x00
> > +#define TWL4030_BCIMDKEY	0x01
> > #define TWL4030_BCIMSTATEC	0x02
> > #define TWL4030_BCIICHG		0x08
> > #define TWL4030_BCIVAC		0x0a
> > @@ -34,6 +36,8 @@
> > #define TWL4030_BCIIREF1	0x27
> > #define TWL4030_BCIIREF2	0x28
> > #define TWL4030_BCIMFKEY	0x11
> > +#define TWL4030_BCIMFEN3	0x14
> > +#define TWL4030_BCIWDKEY	0x21
> > 
> > 
> > 
> > @@ -43,6 +47,7 @@
> > #define TWL4030_BCIAUTOAC	BIT(0)
> > #define TWL4030_CGAIN		BIT(5)
> > #define TWL4030_USBFASTMCHG	BIT(2)
> > +#define TWL4030_USBSLOWMCHG     BIT(1)
> > #define TWL4030_STS_VBUS	BIT(7)
> > #define TWL4030_STS_USB_ID	BIT(2)
> > #define TWL4030_BBCHEN		BIT(4)
> > @@ -84,6 +89,7 @@ static bool allow_usb;
> > module_param(allow_usb, bool, 0644);
> > MODULE_PARM_DESC(allow_usb, "Allow USB charge drawing default current");
> > 
> > +static int do_lin;
> > static int default_usb_current = 100000;
> > module_param(default_usb_current, int, 0644);
> > MODULE_PARM_DESC(default_usb_current, "Default usb current for newly connected devices in uA");
> > @@ -262,16 +268,37 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
> > 			twl4030_charger_set_max_current(600000);
> > 		else
> > 			twl4030_charger_set_max_current(default_usb_current);
> > -		/* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
> > -		ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
> > -		if (ret < 0)
> > -			return ret;
> > -
> > +		if (!do_lin) {
> > +			/* forcing the field BCIAUTOUSB (BOOT_BCI[1]) to 1 */
> > +			ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOUSB);
> > +			if (ret < 0)
> > +				return ret;
> > +		}
> > 		/* forcing USBFASTMCHG(BCIMFSTS4[2]) to 1 */
> > -		ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE, 0,
> > +		ret = twl4030_clear_set(TWL_MODULE_MAIN_CHARGE,
> > +			TWL4030_USBSLOWMCHG,
> > 			TWL4030_USBFASTMCHG, TWL4030_BCIMFSTS4);
> > +		if (do_lin) {
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,
> > +					TWL4030_BCIWDKEY);
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a,
> > +					TWL4030_BCIMDKEY);
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x26,
> > +					TWL4030_BCIMDKEY);
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xf3,
> > +					TWL4030_BCIWDKEY);
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x9c,
> > +					TWL4030_BCIMFKEY);
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xf0,
> > +					TWL4030_BCIMFEN3);
> > +		}
> > 	} else {
> > -		ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0);
> > +		if (!do_lin) {
> > +			ret = twl4030_clear_set_boot_bci(TWL4030_BCIAUTOUSB, 0);
> > +		} else {
> > +			ret = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a,
> > +					TWL4030_BCIMDKEY);
> > +		}
> > 		if (bci->usb_enabled) {
> > 			regulator_disable(bci->usb_reg);
> > 			bci->usb_enabled = 0;
> > @@ -427,6 +454,58 @@ static int twl4030_bci_usb_ncb(struct notifier_block *nb, unsigned long val,
> > 	return NOTIFY_OK;
> > }
> > 
> > +static ssize_t
> > +twl4030_bci_lin_show(struct device *dev, struct device_attribute *attr,
> > +       char *buf)
> > +{
> > +       int ret = -EINVAL;
> > +       u8 val;
> > +       twl_i2c_read_u8(TWL_MODULE_MAIN_CHARGE, &val, TWL4030_BCIMDEN);
> > +       ret = sprintf(buf, "%d\n", (int)val);
> > +       return ret;
> > +}
> > +
> > +static ssize_t
> > +twl4030_bci_lin_store(struct device *dev, struct device_attribute *attr,
> > +               const char *buf, size_t n)
> > +{
> > +       unsigned long   flags;
> > +       int             status = 0;
> > +       if (sysfs_streq(buf, "on")) {
> > +               status  = twl_i2c_write_u8(TWL_MODULE_PM_MASTER, 0x30,
> > +                       TWL4030_PM_MASTER_BOOT_BCI);
> > +
> > +               status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x33,
> > +                       TWL4030_BCIWDKEY);
> > +               status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a,
> > +                       TWL4030_BCIMDKEY);
> > +               status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x26,
> > +                       TWL4030_BCIMDKEY);
> > +               status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xf3,
> > +                       TWL4030_BCIWDKEY);
> > +               do_lin = 1;
> > +
> > +       } else  if (sysfs_streq(buf, "off")) {
> > +               status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0x2a,
> > +                       TWL4030_BCIMDKEY);
> 
> 		do_lin = 0;	????

no.
> 
> > +       } else if (sysfs_streq(buf, "auto")) {
> > +               if (do_lin) {
> > +                       struct twl4030_bci *bci = dev_get_drvdata(dev);
> > +                       status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE,
> > +                               0x2a, TWL4030_BCIMDKEY);
> > +                       do_lin = 0;
> > +                       twl4030_charger_enable_usb(bci, true);
> > +               }
> > +       } else {
> > +               return -EINVAL;
> > +       }
> > +
> > +
> > +       return (status == 0) ? n : status;
> > +}
> > +
> > +static DEVICE_ATTR(lin, 0644, twl4030_bci_lin_show, twl4030_bci_lin_store);
> > +
> > 
> > /*
> >  * sysfs max_current store
> > @@ -524,6 +603,7 @@ static int twl4030_bci_get_property(struct power_supply *psy,
> > 	int is_charging;
> > 	int state;
> > 	int ret;
> > +	u8 i2cval;
> > 
> > 	state = twl4030bci_state(bci);
> > 	if (state < 0)
> > @@ -560,7 +640,8 @@ static int twl4030_bci_get_property(struct power_supply *psy,
> > 		}
> > 		break;
> > 	case POWER_SUPPLY_PROP_CURRENT_NOW:
> > -		if (!is_charging)
> > +		twl4030_bci_read(TWL4030_BCIMFEN3, &i2cval);
> > +		if ((!is_charging) && (i2cval == 0))
> > 			return -ENODATA;
> > 		/* current measurement is shared between AC and USB */
> > 		ret = twl4030_charger_get_current();
> > @@ -673,6 +754,8 @@ static int __init twl4030_bci_probe(struct platform_device *pdev)
> > 
> > 	if (device_create_file(&pdev->dev, &dev_attr_max_current))
> > 		dev_warn(&pdev->dev, "could not create sysfs file\n");
> > +	if (device_create_file(&pdev->dev, &dev_attr_lin))
> > +		dev_warn(&pdev->dev, "could not create sysfs file\n");
> > 
> > 
> > 	twl4030_charger_enable_ac(true);
> > @@ -704,6 +787,7 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev)
> > {
> > 	struct twl4030_bci *bci = platform_get_drvdata(pdev);
> > 	device_remove_file(&pdev->dev, &dev_attr_max_current);
> > +	device_remove_file(&pdev->dev, &dev_attr_lin);
> > 	twl4030_charger_enable_ac(false);
> > 	twl4030_charger_enable_usb(bci, false);
> > 	twl4030_charger_enable_backup(0, 0);
> > -- 
> > 1.7.12
> > 
> > _______________________________________________
> > Gta04-owner mailing list
> > Gta04-owner at goldelico.com
> > http://lists.goldelico.com/mailman/listinfo/gta04-owner
> 
> 
Greetings
Andreas Kemnade
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.goldelico.com/pipermail/gta04-owner/attachments/20130926/ae362810/attachment.bin>


More information about the Gta04-owner mailing list