aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
authorNeilBrown <neil@brown.name>2015-07-29 20:11:24 -0400
committerSebastian Reichel <sre@kernel.org>2015-08-04 23:21:57 -0400
commitb04b908d8a2901c2cc59db87defd9c08bd4293cc (patch)
treecc66542acca233a902d606d775b66c31a42193f9 /drivers/power
parent7f4a633d21331155ee06c5ee44749ed35a3a3cc5 (diff)
twl4030_charger: add ac/mode to match usb/mode
This allows AC charging to be turned off, much like usb charging. "continuous" mode is not available though. Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: NeilBrown <neil@brown.name> Signed-off-by: Sebastian Reichel <sre@kernel.org>
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/twl4030_charger.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c
index de5430deaf23..68117ad23564 100644
--- a/drivers/power/twl4030_charger.c
+++ b/drivers/power/twl4030_charger.c
@@ -114,7 +114,7 @@ struct twl4030_bci {
114 unsigned int ichg_eoc, ichg_lo, ichg_hi; 114 unsigned int ichg_eoc, ichg_lo, ichg_hi;
115 unsigned int usb_cur, ac_cur; 115 unsigned int usb_cur, ac_cur;
116 bool ac_is_active; 116 bool ac_is_active;
117 int usb_mode; /* charging mode requested */ 117 int usb_mode, ac_mode; /* charging mode requested */
118#define CHARGE_OFF 0 118#define CHARGE_OFF 0
119#define CHARGE_AUTO 1 119#define CHARGE_AUTO 1
120#define CHARGE_LINEAR 2 120#define CHARGE_LINEAR 2
@@ -459,10 +459,13 @@ static int twl4030_charger_enable_usb(struct twl4030_bci *bci, bool enable)
459/* 459/*
460 * Enable/Disable AC Charge funtionality. 460 * Enable/Disable AC Charge funtionality.
461 */ 461 */
462static int twl4030_charger_enable_ac(bool enable) 462static int twl4030_charger_enable_ac(struct twl4030_bci *bci, bool enable)
463{ 463{
464 int ret; 464 int ret;
465 465
466 if (bci->ac_mode == CHARGE_OFF)
467 enable = false;
468
466 if (enable) 469 if (enable)
467 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOAC); 470 ret = twl4030_clear_set_boot_bci(0, TWL4030_BCIAUTOAC);
468 else 471 else
@@ -688,9 +691,17 @@ twl4030_bci_mode_store(struct device *dev, struct device_attribute *attr,
688 mode = 2; 691 mode = 2;
689 else 692 else
690 return -EINVAL; 693 return -EINVAL;
691 twl4030_charger_enable_usb(bci, false); 694 if (dev == &bci->ac->dev) {
692 bci->usb_mode = mode; 695 if (mode == 2)
693 status = twl4030_charger_enable_usb(bci, true); 696 return -EINVAL;
697 twl4030_charger_enable_ac(bci, false);
698 bci->ac_mode = mode;
699 status = twl4030_charger_enable_ac(bci, true);
700 } else {
701 twl4030_charger_enable_usb(bci, false);
702 bci->usb_mode = mode;
703 status = twl4030_charger_enable_usb(bci, true);
704 }
694 return (status == 0) ? n : status; 705 return (status == 0) ? n : status;
695} 706}
696 707
@@ -704,9 +715,13 @@ twl4030_bci_mode_show(struct device *dev,
704 struct twl4030_bci *bci = dev_get_drvdata(dev->parent); 715 struct twl4030_bci *bci = dev_get_drvdata(dev->parent);
705 int len = 0; 716 int len = 0;
706 int i; 717 int i;
718 int mode = bci->usb_mode;
719
720 if (dev == &bci->ac->dev)
721 mode = bci->ac_mode;
707 722
708 for (i = 0; i < ARRAY_SIZE(modes); i++) 723 for (i = 0; i < ARRAY_SIZE(modes); i++)
709 if (bci->usb_mode == i) 724 if (mode == i)
710 len += snprintf(buf+len, PAGE_SIZE-len, 725 len += snprintf(buf+len, PAGE_SIZE-len,
711 "[%s] ", modes[i]); 726 "[%s] ", modes[i]);
712 else 727 else
@@ -916,6 +931,7 @@ static int twl4030_bci_probe(struct platform_device *pdev)
916 else 931 else
917 bci->usb_cur = 100000; /* 100mA */ 932 bci->usb_cur = 100000; /* 100mA */
918 bci->usb_mode = CHARGE_AUTO; 933 bci->usb_mode = CHARGE_AUTO;
934 bci->ac_mode = CHARGE_AUTO;
919 935
920 bci->dev = &pdev->dev; 936 bci->dev = &pdev->dev;
921 bci->irq_chg = platform_get_irq(pdev, 0); 937 bci->irq_chg = platform_get_irq(pdev, 0);
@@ -1001,10 +1017,12 @@ static int twl4030_bci_probe(struct platform_device *pdev)
1001 dev_warn(&pdev->dev, "could not create sysfs file\n"); 1017 dev_warn(&pdev->dev, "could not create sysfs file\n");
1002 if (device_create_file(&bci->usb->dev, &dev_attr_mode)) 1018 if (device_create_file(&bci->usb->dev, &dev_attr_mode))
1003 dev_warn(&pdev->dev, "could not create sysfs file\n"); 1019 dev_warn(&pdev->dev, "could not create sysfs file\n");
1020 if (device_create_file(&bci->ac->dev, &dev_attr_mode))
1021 dev_warn(&pdev->dev, "could not create sysfs file\n");
1004 if (device_create_file(&bci->ac->dev, &dev_attr_max_current)) 1022 if (device_create_file(&bci->ac->dev, &dev_attr_max_current))
1005 dev_warn(&pdev->dev, "could not create sysfs file\n"); 1023 dev_warn(&pdev->dev, "could not create sysfs file\n");
1006 1024
1007 twl4030_charger_enable_ac(true); 1025 twl4030_charger_enable_ac(bci, true);
1008 if (!IS_ERR_OR_NULL(bci->transceiver)) 1026 if (!IS_ERR_OR_NULL(bci->transceiver))
1009 twl4030_bci_usb_ncb(&bci->usb_nb, 1027 twl4030_bci_usb_ncb(&bci->usb_nb,
1010 bci->transceiver->last_event, 1028 bci->transceiver->last_event,
@@ -1024,13 +1042,14 @@ static int __exit twl4030_bci_remove(struct platform_device *pdev)
1024{ 1042{
1025 struct twl4030_bci *bci = platform_get_drvdata(pdev); 1043 struct twl4030_bci *bci = platform_get_drvdata(pdev);
1026 1044
1027 twl4030_charger_enable_ac(false); 1045 twl4030_charger_enable_ac(bci, false);
1028 twl4030_charger_enable_usb(bci, false); 1046 twl4030_charger_enable_usb(bci, false);
1029 twl4030_charger_enable_backup(0, 0); 1047 twl4030_charger_enable_backup(0, 0);
1030 1048
1031 device_remove_file(&bci->usb->dev, &dev_attr_max_current); 1049 device_remove_file(&bci->usb->dev, &dev_attr_max_current);
1032 device_remove_file(&bci->usb->dev, &dev_attr_mode); 1050 device_remove_file(&bci->usb->dev, &dev_attr_mode);
1033 device_remove_file(&bci->ac->dev, &dev_attr_max_current); 1051 device_remove_file(&bci->ac->dev, &dev_attr_max_current);
1052 device_remove_file(&bci->ac->dev, &dev_attr_mode);
1034 /* mask interrupts */ 1053 /* mask interrupts */
1035 twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff, 1054 twl_i2c_write_u8(TWL4030_MODULE_INTERRUPTS, 0xff,
1036 TWL4030_INTERRUPTS_BCIIMR1A); 1055 TWL4030_INTERRUPTS_BCIIMR1A);