Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply

Pull power supply and reset updates from Sebastian Reichel:
"Battery/charger driver changes:

- convert charger-manager binding to YAML

- drop bd70528-charger driver

- drop pm2301-charger driver

- introduce rt5033-battery driver

- misc improvements and fixes"

* tag 'for-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (42 commits)
power: supply: ab8500: Fix an old bug
power: supply: axp288_fuel_gauge: remove redundant continue statement
power: supply: axp288_fuel_gauge: Make "T3 MRD" no_battery_list DMI entry more generic
power: supply: axp288_fuel_gauge: Rename fuel_gauge_blacklist to no_battery_list
power: supply: bq24190_charger: drop of_match_ptr() from device ID table
drivers: power: add missing MODULE_DEVICE_TABLE in keystone-reset.c
power: supply: ab8500: add missing MODULE_DEVICE_TABLE
power: supply: charger-manager: add missing MODULE_DEVICE_TABLE
power: reset: regulator-poweroff: add missing MODULE_DEVICE_TABLE
power: supply: cpcap-charger: get the battery inserted infomation from cpcap-battery
power: supply: cpcap-battery: invalidate config when incompatible measurements are read
power: supply: axp20x_battery: allow disabling battery charging
power: supply: max17040: drop unused platform data support
power: supply: max17040: simplify POWER_SUPPLY_PROP_ONLINE
power: supply: max17040: remove non-working POWER_SUPPLY_PROP_STATUS
power: reset: at91-sama5d2_shdwc: Remove redundant error printing in at91_shdwc_probe()
power: reset: gpio-poweroff: add missing MODULE_DEVICE_TABLE
power: supply: rt5033_battery: Fix device tree enumeration
dt-bindings: power: supply: Add DT schema for richtek,rt5033-battery
power: supply: Drop BD70528 support
...

+1123 -2672
-91
Documentation/devicetree/bindings/power/supply/charger-manager.txt
··· 1 - charger-manager bindings 2 - ~~~~~~~~~~~~~~~~~~~~~~~~ 3 - 4 - Required properties : 5 - - compatible : "charger-manager" 6 - - <>-supply : for regulator consumer, named according to cm-regulator-name 7 - - cm-chargers : name of chargers 8 - - cm-fuel-gauge : name of battery fuel gauge 9 - - subnode <regulator> : 10 - - cm-regulator-name : name of charger regulator 11 - - subnode <cable> : 12 - - cm-cable-name : name of charger cable - one of USB, USB-HOST, 13 - SDP, DCP, CDP, ACA, FAST-CHARGER, SLOW-CHARGER, WPT, 14 - PD, DOCK, JIG, or MECHANICAL 15 - - cm-cable-extcon : name of extcon dev 16 - (optional) - cm-cable-min : minimum current of cable 17 - (optional) - cm-cable-max : maximum current of cable 18 - 19 - Optional properties : 20 - - cm-name : charger manager's name (default : "battery") 21 - - cm-poll-mode : polling mode - 0 for disabled, 1 for always, 2 for when 22 - external power is connected, or 3 for when charging. If not present, 23 - then polling is disabled 24 - - cm-poll-interval : polling interval (in ms) 25 - - cm-battery-stat : battery status - 0 for battery always present, 1 for no 26 - battery, 2 to check presence via fuel gauge, or 3 to check presence 27 - via charger 28 - - cm-fullbatt-vchkdrop-volt : voltage drop (in uV) before restarting charging 29 - - cm-fullbatt-voltage : voltage (in uV) of full battery 30 - - cm-fullbatt-soc : state of charge to consider as full battery 31 - - cm-fullbatt-capacity : capcity (in uAh) to consider as full battery 32 - - cm-thermal-zone : name of external thermometer's thermal zone 33 - - cm-battery-* : threshold battery temperature for charging 34 - -cold : critical cold temperature of battery for charging 35 - -cold-in-minus : flag that cold temperature is in minus degrees 36 - -hot : critical hot temperature of battery for charging 37 - -temp-diff : temperature difference to allow recharging 38 - - cm-dis/charging-max = limits of charging duration 39 - 40 - Deprecated properties: 41 - - cm-num-chargers 42 - - cm-fullbatt-vchkdrop-ms 43 - 44 - Example : 45 - charger-manager@0 { 46 - compatible = "charger-manager"; 47 - chg-reg-supply = <&charger_regulator>; 48 - 49 - cm-name = "battery"; 50 - /* Always polling ON : 30s */ 51 - cm-poll-mode = <1>; 52 - cm-poll-interval = <30000>; 53 - 54 - cm-fullbatt-vchkdrop-volt = <150000>; 55 - cm-fullbatt-soc = <100>; 56 - 57 - cm-battery-stat = <3>; 58 - 59 - cm-chargers = "charger0", "charger1", "charger2"; 60 - 61 - cm-fuel-gauge = "fuelgauge0"; 62 - 63 - cm-thermal-zone = "thermal_zone.1" 64 - /* in deci centigrade */ 65 - cm-battery-cold = <50>; 66 - cm-battery-cold-in-minus; 67 - cm-battery-hot = <800>; 68 - cm-battery-temp-diff = <100>; 69 - 70 - /* Allow charging for 5hr */ 71 - cm-charging-max = <18000000>; 72 - /* Allow discharging for 2hr */ 73 - cm-discharging-max = <7200000>; 74 - 75 - regulator@0 { 76 - cm-regulator-name = "chg-reg"; 77 - cable@0 { 78 - cm-cable-name = "USB"; 79 - cm-cable-extcon = "extcon-dev.0"; 80 - cm-cable-min = <475000>; 81 - cm-cable-max = <500000>; 82 - }; 83 - cable@1 { 84 - cm-cable-name = "SDP"; 85 - cm-cable-extcon = "extcon-dev.0"; 86 - cm-cable-min = <650000>; 87 - cm-cable-max = <675000>; 88 - }; 89 - }; 90 - 91 - };
+215
Documentation/devicetree/bindings/power/supply/charger-manager.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/power/supply/charger-manager.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Charger Manager 8 + 9 + maintainers: 10 + - Sebastian Reichel <sre@kernel.org> 11 + 12 + description: | 13 + Binding for the legacy charger manager driver. 14 + Please do not use for new products. 15 + 16 + properties: 17 + compatible: 18 + const: charger-manager 19 + 20 + cm-chargers: 21 + description: name of chargers 22 + $ref: /schemas/types.yaml#/definitions/string-array 23 + 24 + cm-num-chargers: 25 + $ref: /schemas/types.yaml#/definitions/uint32 26 + deprecated: true 27 + 28 + cm-fuel-gauge: 29 + description: name of battery fuel gauge 30 + $ref: /schemas/types.yaml#/definitions/string 31 + 32 + cm-name: 33 + description: name of the charger manager 34 + default: battery 35 + $ref: /schemas/types.yaml#/definitions/string 36 + 37 + cm-poll-mode: 38 + description: polling mode 39 + default: 0 40 + enum: 41 + - 0 # disabled 42 + - 1 # always 43 + - 2 # when external power is connected 44 + - 3 # when charging 45 + 46 + cm-poll-interval: 47 + description: polling interval (in ms) 48 + $ref: /schemas/types.yaml#/definitions/uint32 49 + 50 + cm-battery-stat: 51 + description: battery status 52 + enum: 53 + - 0 # battery always present 54 + - 1 # no battery 55 + - 2 # check presence via fuel gauge 56 + - 3 # check presence via charger 57 + 58 + cm-fullbatt-vchkdrop-volt: 59 + description: voltage drop before restarting charging in uV 60 + $ref: /schemas/types.yaml#/definitions/uint32 61 + 62 + cm-fullbatt-vchkdrop-ms: 63 + deprecated: true 64 + 65 + cm-fullbatt-voltage: 66 + description: voltage of full battery in uV 67 + $ref: /schemas/types.yaml#/definitions/uint32 68 + 69 + cm-fullbatt-soc: 70 + description: state of charge to consider as full battery in % 71 + $ref: /schemas/types.yaml#/definitions/uint32 72 + 73 + cm-fullbatt-capacity: 74 + description: capcity to consider as full battery in uAh 75 + $ref: /schemas/types.yaml#/definitions/uint32 76 + 77 + cm-thermal-zone: 78 + description: name of external thermometer's thermal zone 79 + $ref: /schemas/types.yaml#/definitions/string 80 + 81 + cm-discharging-max: 82 + description: limits of discharging duration in ms 83 + $ref: /schemas/types.yaml#/definitions/uint32 84 + 85 + cm-charging-max: 86 + description: limits of charging duration in ms 87 + $ref: /schemas/types.yaml#/definitions/uint32 88 + 89 + cm-battery-cold: 90 + description: critical cold temperature of battery for charging in deci-degree celsius 91 + $ref: /schemas/types.yaml#/definitions/uint32 92 + 93 + cm-battery-cold-in-minus: 94 + description: if set cm-battery-cold temperature is in minus degrees 95 + type: boolean 96 + 97 + cm-battery-hot: 98 + description: critical hot temperature of battery for charging in deci-degree celsius 99 + $ref: /schemas/types.yaml#/definitions/uint32 100 + 101 + cm-battery-temp-diff: 102 + description: temperature difference to allow recharging in deci-degree celsius 103 + $ref: /schemas/types.yaml#/definitions/uint32 104 + 105 + patternProperties: 106 + "-supply$": 107 + description: regulator consumer, named according to cm-regulator-name 108 + $ref: /schemas/types.yaml#/definitions/phandle 109 + 110 + "^regulator[@-][0-9]$": 111 + type: object 112 + properties: 113 + cm-regulator-name: 114 + description: name of charger regulator 115 + $ref: /schemas/types.yaml#/definitions/string 116 + 117 + required: 118 + - cm-regulator-name 119 + 120 + additionalProperties: false 121 + 122 + patternProperties: 123 + "^cable[@-][0-9]$": 124 + type: object 125 + properties: 126 + cm-cable-name: 127 + description: name of charger cable 128 + enum: 129 + - USB 130 + - USB-HOST 131 + - SDP 132 + - DCP 133 + - CDP 134 + - ACA 135 + - FAST-CHARGER 136 + - SLOW-CHARGER 137 + - WPT 138 + - PD 139 + - DOCK 140 + - JIG 141 + - MECHANICAL 142 + 143 + cm-cable-extcon: 144 + description: name of extcon dev 145 + $ref: /schemas/types.yaml#/definitions/string 146 + 147 + cm-cable-min: 148 + description: minimum current of cable in uA 149 + $ref: /schemas/types.yaml#/definitions/uint32 150 + 151 + cm-cable-max: 152 + description: maximum current of cable in uA 153 + $ref: /schemas/types.yaml#/definitions/uint32 154 + 155 + required: 156 + - cm-cable-name 157 + - cm-cable-extcon 158 + 159 + additionalProperties: false 160 + 161 + required: 162 + - compatible 163 + - cm-chargers 164 + - cm-fuel-gauge 165 + 166 + additionalProperties: false 167 + 168 + examples: 169 + - | 170 + charger-manager { 171 + compatible = "charger-manager"; 172 + chg-reg-supply = <&charger_regulator>; 173 + 174 + cm-name = "battery"; 175 + /* Always polling ON : 30s */ 176 + cm-poll-mode = <1>; 177 + cm-poll-interval = <30000>; 178 + 179 + cm-fullbatt-vchkdrop-volt = <150000>; 180 + cm-fullbatt-soc = <100>; 181 + 182 + cm-battery-stat = <3>; 183 + 184 + cm-chargers = "charger0", "charger1", "charger2"; 185 + 186 + cm-fuel-gauge = "fuelgauge0"; 187 + 188 + cm-thermal-zone = "thermal_zone.1"; 189 + /* in deci centigrade */ 190 + cm-battery-cold = <50>; 191 + cm-battery-cold-in-minus; 192 + cm-battery-hot = <800>; 193 + cm-battery-temp-diff = <100>; 194 + 195 + /* Allow charging for 5hr */ 196 + cm-charging-max = <18000000>; 197 + /* Allow discharging for 2hr */ 198 + cm-discharging-max = <7200000>; 199 + 200 + regulator-0 { 201 + cm-regulator-name = "chg-reg"; 202 + cable-0 { 203 + cm-cable-name = "USB"; 204 + cm-cable-extcon = "extcon-dev.0"; 205 + cm-cable-min = <475000>; 206 + cm-cable-max = <500000>; 207 + }; 208 + cable-1 { 209 + cm-cable-name = "SDP"; 210 + cm-cable-extcon = "extcon-dev.0"; 211 + cm-cable-min = <650000>; 212 + cm-cable-max = <675000>; 213 + }; 214 + }; 215 + };
+1 -1
Documentation/devicetree/bindings/power/supply/maxim,max17040.yaml
··· 89 89 reg = <0x36>; 90 90 maxim,alert-low-soc-level = <10>; 91 91 interrupt-parent = <&gpio7>; 92 - interrupts = <2 IRQ_TYPE_EDGE_FALLING>; 92 + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; 93 93 wakeup-source; 94 94 }; 95 95 };
+54
Documentation/devicetree/bindings/power/supply/richtek,rt5033-battery.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: "http://devicetree.org/schemas/power/supply/richtek,rt5033-battery.yaml#" 5 + $schema: "http://devicetree.org/meta-schemas/core.yaml#" 6 + 7 + title: Richtek RT5033 PMIC Fuel Gauge 8 + 9 + maintainers: 10 + - Stephan Gerhold <stephan@gerhold.net> 11 + 12 + allOf: 13 + - $ref: power-supply.yaml# 14 + 15 + properties: 16 + compatible: 17 + const: richtek,rt5033-battery 18 + 19 + reg: 20 + maxItems: 1 21 + 22 + interrupts: 23 + maxItems: 1 24 + 25 + required: 26 + - compatible 27 + - reg 28 + 29 + additionalProperties: false 30 + 31 + examples: 32 + - | 33 + i2c { 34 + #address-cells = <1>; 35 + #size-cells = <0>; 36 + 37 + battery@35 { 38 + compatible = "richtek,rt5033-battery"; 39 + reg = <0x35>; 40 + }; 41 + }; 42 + - | 43 + #include <dt-bindings/interrupt-controller/irq.h> 44 + i2c { 45 + #address-cells = <1>; 46 + #size-cells = <0>; 47 + 48 + battery@35 { 49 + compatible = "richtek,rt5033-battery"; 50 + reg = <0x35>; 51 + interrupt-parent = <&msmgpio>; 52 + interrupts = <121 IRQ_TYPE_EDGE_FALLING>; 53 + }; 54 + };
+2 -1
MAINTAINERS
··· 14827 14827 F: Documentation/ABI/testing/sysfs-class-power 14828 14828 F: Documentation/devicetree/bindings/power/supply/ 14829 14829 F: drivers/power/supply/ 14830 + F: include/linux/power/ 14830 14831 F: include/linux/power_supply.h 14831 14832 14832 14833 POWERNV OPERATOR PANEL LCD DISPLAY DRIVER ··· 16214 16213 F: drivers/s390/scsi/zfcp_* 16215 16214 16216 16215 S3C ADC BATTERY DRIVER 16217 - M: Krzysztof Kozlowski <krzk@kernel.org> 16216 + M: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> 16218 16217 L: linux-samsung-soc@vger.kernel.org 16219 16218 S: Odd Fixes 16220 16219 F: drivers/power/supply/s3c_adc_battery.c
+1 -3
drivers/power/reset/at91-sama5d2_shdwc.c
··· 351 351 352 352 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 353 353 at91_shdwc->shdwc_base = devm_ioremap_resource(&pdev->dev, res); 354 - if (IS_ERR(at91_shdwc->shdwc_base)) { 355 - dev_err(&pdev->dev, "Could not map reset controller address\n"); 354 + if (IS_ERR(at91_shdwc->shdwc_base)) 356 355 return PTR_ERR(at91_shdwc->shdwc_base); 357 - } 358 356 359 357 match = of_match_node(at91_shdwc_of_match, pdev->dev.of_node); 360 358 at91_shdwc->rcfg = match->data;
+1
drivers/power/reset/gpio-poweroff.c
··· 90 90 { .compatible = "gpio-poweroff", }, 91 91 {}, 92 92 }; 93 + MODULE_DEVICE_TABLE(of, of_gpio_poweroff_match); 93 94 94 95 static struct platform_driver gpio_poweroff_driver = { 95 96 .probe = gpio_poweroff_probe,
+1
drivers/power/reset/keystone-reset.c
··· 71 71 {.compatible = "ti,keystone-reset", }, 72 72 {}, 73 73 }; 74 + MODULE_DEVICE_TABLE(of, rsctrl_of_match); 74 75 75 76 static int rsctrl_probe(struct platform_device *pdev) 76 77 {
+1
drivers/power/reset/regulator-poweroff.c
··· 64 64 { .compatible = "regulator-poweroff", }, 65 65 {}, 66 66 }; 67 + MODULE_DEVICE_TABLE(of, of_regulator_poweroff_match); 67 68 68 69 static struct platform_driver regulator_poweroff_driver = { 69 70 .probe = regulator_poweroff_probe,
+2 -10
drivers/power/supply/Kconfig
··· 712 712 713 713 config BATTERY_RT5033 714 714 tristate "RT5033 fuel gauge support" 715 - depends on MFD_RT5033 715 + depends on I2C 716 + select REGMAP_I2C 716 717 help 717 718 This adds support for battery fuel gauge in Richtek RT5033 PMIC. 718 719 The fuelgauge calculates and determines the battery state of charge ··· 760 759 help 761 760 Say Y to enable support for Microchip UCS1002 Programmable 762 761 USB Port Power Controller with Charger Emulation. 763 - 764 - config CHARGER_BD70528 765 - tristate "ROHM bd70528 charger driver" 766 - depends on MFD_ROHM_BD70528 767 - select LINEAR_RANGES 768 - help 769 - Say Y here to enable support for getting battery status 770 - information and altering charger configurations from charger 771 - block of the ROHM BD70528 Power Management IC. 772 762 773 763 config CHARGER_BD99954 774 764 tristate "ROHM bd99954 charger driver"
+1 -2
drivers/power/supply/Makefile
··· 60 60 obj-$(CONFIG_CHARGER_88PM860X) += 88pm860x_charger.o 61 61 obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o 62 62 obj-$(CONFIG_BATTERY_RX51) += rx51_battery.o 63 - obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o pm2301_charger.o 63 + obj-$(CONFIG_AB8500_BM) += ab8500_bmdata.o ab8500_charger.o ab8500_fg.o ab8500_btemp.o abx500_chargalg.o 64 64 obj-$(CONFIG_CHARGER_CPCAP) += cpcap-charger.o 65 65 obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o 66 66 obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o ··· 96 96 obj-$(CONFIG_CHARGER_SC2731) += sc2731_charger.o 97 97 obj-$(CONFIG_FUEL_GAUGE_SC27XX) += sc27xx_fuel_gauge.o 98 98 obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o 99 - obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o 100 99 obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o 101 100 obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o 102 101 obj-$(CONFIG_RN5T618_POWER) += rn5t618_power.o
+4 -3
drivers/power/supply/ab8500-bm.h
··· 506 506 int usb_safety_tmr_h; 507 507 int bkup_bat_v; 508 508 int bkup_bat_i; 509 - bool autopower_cfg; 510 - bool ac_enabled; 511 - bool usb_enabled; 512 509 bool no_maintenance; 513 510 bool capacity_scaling; 514 511 bool chg_unknown_bat; ··· 726 729 int ab8500_bm_of_probe(struct device *dev, 727 730 struct device_node *np, 728 731 struct abx500_bm_data *bm); 732 + 733 + extern struct platform_driver ab8500_fg_driver; 734 + extern struct platform_driver ab8500_btemp_driver; 735 + extern struct platform_driver abx500_chargalg_driver; 729 736 730 737 #endif /* _AB8500_CHARGER_H_ */
+1 -1
drivers/power/supply/ab8500-chargalg.h
··· 15 15 * - POWER_SUPPLY_TYPE_USB, 16 16 * because only them store as drv_data pointer to struct ux500_charger. 17 17 */ 18 - #define psy_to_ux500_charger(x) power_supply_get_drvdata(psy) 18 + #define psy_to_ux500_charger(x) power_supply_get_drvdata(x) 19 19 20 20 /* Forward declaration */ 21 21 struct ux500_charger;
+52 -74
drivers/power/supply/ab8500_btemp.c
··· 13 13 #include <linux/init.h> 14 14 #include <linux/module.h> 15 15 #include <linux/device.h> 16 + #include <linux/component.h> 16 17 #include <linux/interrupt.h> 17 18 #include <linux/delay.h> 18 19 #include <linux/slab.h> ··· 933 932 return 0; 934 933 } 935 934 936 - static int ab8500_btemp_remove(struct platform_device *pdev) 937 - { 938 - struct ab8500_btemp *di = platform_get_drvdata(pdev); 939 - int i, irq; 940 - 941 - /* Disable interrupts */ 942 - for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { 943 - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); 944 - free_irq(irq, di); 945 - } 946 - 947 - /* Delete the work queue */ 948 - destroy_workqueue(di->btemp_wq); 949 - 950 - flush_scheduled_work(); 951 - power_supply_unregister(di->btemp_psy); 952 - 953 - return 0; 954 - } 955 - 956 935 static char *supply_interface[] = { 957 936 "ab8500_chargalg", 958 937 "ab8500_fg", ··· 947 966 .external_power_changed = ab8500_btemp_external_power_changed, 948 967 }; 949 968 969 + static int ab8500_btemp_bind(struct device *dev, struct device *master, 970 + void *data) 971 + { 972 + struct ab8500_btemp *di = dev_get_drvdata(dev); 973 + 974 + /* Create a work queue for the btemp */ 975 + di->btemp_wq = 976 + alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); 977 + if (di->btemp_wq == NULL) { 978 + dev_err(dev, "failed to create work queue\n"); 979 + return -ENOMEM; 980 + } 981 + 982 + /* Kick off periodic temperature measurements */ 983 + ab8500_btemp_periodic(di, true); 984 + 985 + return 0; 986 + } 987 + 988 + static void ab8500_btemp_unbind(struct device *dev, struct device *master, 989 + void *data) 990 + { 991 + struct ab8500_btemp *di = dev_get_drvdata(dev); 992 + 993 + /* Delete the work queue */ 994 + destroy_workqueue(di->btemp_wq); 995 + flush_scheduled_work(); 996 + } 997 + 998 + static const struct component_ops ab8500_btemp_component_ops = { 999 + .bind = ab8500_btemp_bind, 1000 + .unbind = ab8500_btemp_unbind, 1001 + }; 1002 + 950 1003 static int ab8500_btemp_probe(struct platform_device *pdev) 951 1004 { 952 - struct device_node *np = pdev->dev.of_node; 953 1005 struct power_supply_config psy_cfg = {}; 954 1006 struct device *dev = &pdev->dev; 955 1007 struct ab8500_btemp *di; ··· 994 980 return -ENOMEM; 995 981 996 982 di->bm = &ab8500_bm_data; 997 - 998 - ret = ab8500_bm_of_probe(dev, np, di->bm); 999 - if (ret) { 1000 - dev_err(dev, "failed to get battery information\n"); 1001 - return ret; 1002 - } 1003 983 1004 984 /* get parent data */ 1005 985 di->dev = dev; ··· 1019 1011 psy_cfg.num_supplicants = ARRAY_SIZE(supply_interface); 1020 1012 psy_cfg.drv_data = di; 1021 1013 1022 - /* Create a work queue for the btemp */ 1023 - di->btemp_wq = 1024 - alloc_workqueue("ab8500_btemp_wq", WQ_MEM_RECLAIM, 0); 1025 - if (di->btemp_wq == NULL) { 1026 - dev_err(dev, "failed to create work queue\n"); 1027 - return -ENOMEM; 1028 - } 1029 - 1030 1014 /* Init work for measuring temperature periodically */ 1031 1015 INIT_DEFERRABLE_WORK(&di->btemp_periodic_work, 1032 1016 ab8500_btemp_periodic_work); ··· 1031 1031 AB8500_BTEMP_HIGH_TH, &val); 1032 1032 if (ret < 0) { 1033 1033 dev_err(dev, "%s ab8500 read failed\n", __func__); 1034 - goto free_btemp_wq; 1034 + return ret; 1035 1035 } 1036 1036 switch (val) { 1037 1037 case BTEMP_HIGH_TH_57_0: ··· 1050 1050 } 1051 1051 1052 1052 /* Register BTEMP power supply class */ 1053 - di->btemp_psy = power_supply_register(dev, &ab8500_btemp_desc, 1054 - &psy_cfg); 1053 + di->btemp_psy = devm_power_supply_register(dev, &ab8500_btemp_desc, 1054 + &psy_cfg); 1055 1055 if (IS_ERR(di->btemp_psy)) { 1056 1056 dev_err(dev, "failed to register BTEMP psy\n"); 1057 - ret = PTR_ERR(di->btemp_psy); 1058 - goto free_btemp_wq; 1057 + return PTR_ERR(di->btemp_psy); 1059 1058 } 1060 1059 1061 1060 /* Register interrupts */ 1062 1061 for (i = 0; i < ARRAY_SIZE(ab8500_btemp_irq); i++) { 1063 1062 irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); 1064 - if (irq < 0) { 1065 - ret = irq; 1066 - goto free_irq; 1067 - } 1063 + if (irq < 0) 1064 + return irq; 1068 1065 1069 - ret = request_threaded_irq(irq, NULL, ab8500_btemp_irq[i].isr, 1066 + ret = devm_request_threaded_irq(dev, irq, NULL, 1067 + ab8500_btemp_irq[i].isr, 1070 1068 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 1071 1069 ab8500_btemp_irq[i].name, di); 1072 1070 1073 1071 if (ret) { 1074 1072 dev_err(dev, "failed to request %s IRQ %d: %d\n" 1075 1073 , ab8500_btemp_irq[i].name, irq, ret); 1076 - goto free_irq; 1074 + return ret; 1077 1075 } 1078 1076 dev_dbg(dev, "Requested %s IRQ %d: %d\n", 1079 1077 ab8500_btemp_irq[i].name, irq, ret); ··· 1079 1081 1080 1082 platform_set_drvdata(pdev, di); 1081 1083 1082 - /* Kick off periodic temperature measurements */ 1083 - ab8500_btemp_periodic(di, true); 1084 1084 list_add_tail(&di->node, &ab8500_btemp_list); 1085 1085 1086 - return ret; 1086 + return component_add(dev, &ab8500_btemp_component_ops); 1087 + } 1087 1088 1088 - free_irq: 1089 - /* We also have to free all successfully registered irqs */ 1090 - for (i = i - 1; i >= 0; i--) { 1091 - irq = platform_get_irq_byname(pdev, ab8500_btemp_irq[i].name); 1092 - free_irq(irq, di); 1093 - } 1089 + static int ab8500_btemp_remove(struct platform_device *pdev) 1090 + { 1091 + component_del(&pdev->dev, &ab8500_btemp_component_ops); 1094 1092 1095 - power_supply_unregister(di->btemp_psy); 1096 - free_btemp_wq: 1097 - destroy_workqueue(di->btemp_wq); 1098 - return ret; 1093 + return 0; 1099 1094 } 1100 1095 1101 1096 static SIMPLE_DEV_PM_OPS(ab8500_btemp_pm_ops, ab8500_btemp_suspend, ab8500_btemp_resume); ··· 1097 1106 { .compatible = "stericsson,ab8500-btemp", }, 1098 1107 { }, 1099 1108 }; 1109 + MODULE_DEVICE_TABLE(of, ab8500_btemp_match); 1100 1110 1101 - static struct platform_driver ab8500_btemp_driver = { 1111 + struct platform_driver ab8500_btemp_driver = { 1102 1112 .probe = ab8500_btemp_probe, 1103 1113 .remove = ab8500_btemp_remove, 1104 1114 .driver = { ··· 1108 1116 .pm = &ab8500_btemp_pm_ops, 1109 1117 }, 1110 1118 }; 1111 - 1112 - static int __init ab8500_btemp_init(void) 1113 - { 1114 - return platform_driver_register(&ab8500_btemp_driver); 1115 - } 1116 - 1117 - static void __exit ab8500_btemp_exit(void) 1118 - { 1119 - platform_driver_unregister(&ab8500_btemp_driver); 1120 - } 1121 - 1122 - device_initcall(ab8500_btemp_init); 1123 - module_exit(ab8500_btemp_exit); 1124 - 1125 1119 MODULE_LICENSE("GPL v2"); 1126 1120 MODULE_AUTHOR("Johan Palsson, Karl Komierowski, Arun R Murthy"); 1127 1121 MODULE_ALIAS("platform:ab8500-btemp");
+234 -163
drivers/power/supply/ab8500_charger.c
··· 13 13 #include <linux/init.h> 14 14 #include <linux/module.h> 15 15 #include <linux/device.h> 16 + #include <linux/component.h> 16 17 #include <linux/interrupt.h> 17 18 #include <linux/delay.h> 18 19 #include <linux/notifier.h> ··· 415 414 static void ab8500_power_supply_changed(struct ab8500_charger *di, 416 415 struct power_supply *psy) 417 416 { 417 + /* 418 + * This happens if we get notifications or interrupts and 419 + * the platform has been configured not to support one or 420 + * other type of charging. 421 + */ 422 + if (!psy) 423 + return; 424 + 418 425 if (di->autopower_cfg) { 419 426 if (!di->usb.charger_connected && 420 427 !di->ac.charger_connected && ··· 449 440 if (!connected) 450 441 di->flags.vbus_drop_end = false; 451 442 452 - sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, "present"); 443 + /* 444 + * Sometimes the platform is configured not to support 445 + * USB charging and no psy has been created, but we still 446 + * will get these notifications. 447 + */ 448 + if (di->usb_chg.psy) { 449 + sysfs_notify(&di->usb_chg.psy->dev.kobj, NULL, 450 + "present"); 451 + } 453 452 454 453 if (connected) { 455 454 mutex_lock(&di->charger_attached_mutex); ··· 3188 3171 enum ab8500_usb_state bm_usb_state; 3189 3172 unsigned mA = *((unsigned *)power); 3190 3173 3191 - if (!di) 3192 - return NOTIFY_DONE; 3193 - 3194 3174 if (event != USB_EVENT_VBUS) { 3195 3175 dev_dbg(di->dev, "not a standard host, returning\n"); 3196 3176 return NOTIFY_DONE; ··· 3290 3276 .notifier_call = ab8500_external_charger_prepare, 3291 3277 }; 3292 3278 3293 - static int ab8500_charger_remove(struct platform_device *pdev) 3294 - { 3295 - struct ab8500_charger *di = platform_get_drvdata(pdev); 3296 - int i, irq, ret; 3297 - 3298 - /* Disable AC charging */ 3299 - ab8500_charger_ac_en(&di->ac_chg, false, 0, 0); 3300 - 3301 - /* Disable USB charging */ 3302 - ab8500_charger_usb_en(&di->usb_chg, false, 0, 0); 3303 - 3304 - /* Disable interrupts */ 3305 - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { 3306 - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); 3307 - free_irq(irq, di); 3308 - } 3309 - 3310 - /* Backup battery voltage and current disable */ 3311 - ret = abx500_mask_and_set_register_interruptible(di->dev, 3312 - AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, 0); 3313 - if (ret < 0) 3314 - dev_err(di->dev, "%s mask and set failed\n", __func__); 3315 - 3316 - usb_unregister_notifier(di->usb_phy, &di->nb); 3317 - usb_put_phy(di->usb_phy); 3318 - 3319 - /* Delete the work queue */ 3320 - destroy_workqueue(di->charger_wq); 3321 - 3322 - /* Unregister external charger enable notifier */ 3323 - if (!di->ac_chg.enabled) 3324 - blocking_notifier_chain_unregister( 3325 - &charger_notifier_list, &charger_nb); 3326 - 3327 - flush_scheduled_work(); 3328 - if (di->usb_chg.enabled) 3329 - power_supply_unregister(di->usb_chg.psy); 3330 - 3331 - if (di->ac_chg.enabled && !di->ac_chg.external) 3332 - power_supply_unregister(di->ac_chg.psy); 3333 - 3334 - return 0; 3335 - } 3336 - 3337 3279 static char *supply_interface[] = { 3338 3280 "ab8500_chargalg", 3339 3281 "ab8500_fg", ··· 3312 3342 .get_property = ab8500_charger_usb_get_property, 3313 3343 }; 3314 3344 3345 + static int ab8500_charger_bind(struct device *dev) 3346 + { 3347 + struct ab8500_charger *di = dev_get_drvdata(dev); 3348 + int ch_stat; 3349 + int ret; 3350 + 3351 + /* Create a work queue for the charger */ 3352 + di->charger_wq = alloc_ordered_workqueue("ab8500_charger_wq", 3353 + WQ_MEM_RECLAIM); 3354 + if (di->charger_wq == NULL) { 3355 + dev_err(dev, "failed to create work queue\n"); 3356 + return -ENOMEM; 3357 + } 3358 + 3359 + ch_stat = ab8500_charger_detect_chargers(di, false); 3360 + 3361 + if (ch_stat & AC_PW_CONN) { 3362 + if (is_ab8500(di->parent)) 3363 + queue_delayed_work(di->charger_wq, 3364 + &di->ac_charger_attached_work, 3365 + HZ); 3366 + } 3367 + if (ch_stat & USB_PW_CONN) { 3368 + if (is_ab8500(di->parent)) 3369 + queue_delayed_work(di->charger_wq, 3370 + &di->usb_charger_attached_work, 3371 + HZ); 3372 + di->vbus_detected = true; 3373 + di->vbus_detected_start = true; 3374 + queue_work(di->charger_wq, 3375 + &di->detect_usb_type_work); 3376 + } 3377 + 3378 + ret = component_bind_all(dev, di); 3379 + if (ret) { 3380 + dev_err(dev, "can't bind component devices\n"); 3381 + return ret; 3382 + } 3383 + 3384 + return 0; 3385 + } 3386 + 3387 + static void ab8500_charger_unbind(struct device *dev) 3388 + { 3389 + struct ab8500_charger *di = dev_get_drvdata(dev); 3390 + int ret; 3391 + 3392 + /* Disable AC charging */ 3393 + ab8500_charger_ac_en(&di->ac_chg, false, 0, 0); 3394 + 3395 + /* Disable USB charging */ 3396 + ab8500_charger_usb_en(&di->usb_chg, false, 0, 0); 3397 + 3398 + /* Backup battery voltage and current disable */ 3399 + ret = abx500_mask_and_set_register_interruptible(di->dev, 3400 + AB8500_RTC, AB8500_RTC_CTRL_REG, RTC_BUP_CH_ENA, 0); 3401 + if (ret < 0) 3402 + dev_err(di->dev, "%s mask and set failed\n", __func__); 3403 + 3404 + /* Delete the work queue */ 3405 + destroy_workqueue(di->charger_wq); 3406 + 3407 + flush_scheduled_work(); 3408 + 3409 + /* Unbind fg, btemp, algorithm */ 3410 + component_unbind_all(dev, di); 3411 + } 3412 + 3413 + static const struct component_master_ops ab8500_charger_comp_ops = { 3414 + .bind = ab8500_charger_bind, 3415 + .unbind = ab8500_charger_unbind, 3416 + }; 3417 + 3418 + static struct platform_driver *const ab8500_charger_component_drivers[] = { 3419 + &ab8500_fg_driver, 3420 + &ab8500_btemp_driver, 3421 + &abx500_chargalg_driver, 3422 + }; 3423 + 3424 + static int ab8500_charger_compare_dev(struct device *dev, void *data) 3425 + { 3426 + return dev == data; 3427 + } 3428 + 3315 3429 static int ab8500_charger_probe(struct platform_device *pdev) 3316 3430 { 3317 - struct device_node *np = pdev->dev.of_node; 3431 + struct device *dev = &pdev->dev; 3432 + struct device_node *np = dev->of_node; 3433 + struct component_match *match = NULL; 3318 3434 struct power_supply_config ac_psy_cfg = {}, usb_psy_cfg = {}; 3319 3435 struct ab8500_charger *di; 3320 - int irq, i, charger_status, ret = 0, ch_stat; 3321 - struct device *dev = &pdev->dev; 3436 + int charger_status; 3437 + int i, irq; 3438 + int ret; 3322 3439 3323 3440 di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); 3324 3441 if (!di) ··· 3450 3393 return ret; 3451 3394 } 3452 3395 3396 + /* 3397 + * VDD ADC supply needs to be enabled from this driver when there 3398 + * is a charger connected to avoid erroneous BTEMP_HIGH/LOW 3399 + * interrupts during charging 3400 + */ 3401 + di->regu = devm_regulator_get(dev, "vddadc"); 3402 + if (IS_ERR(di->regu)) { 3403 + ret = PTR_ERR(di->regu); 3404 + dev_err(dev, "failed to get vddadc regulator\n"); 3405 + return ret; 3406 + } 3407 + 3408 + /* Request interrupts */ 3409 + for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { 3410 + irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); 3411 + if (irq < 0) 3412 + return irq; 3413 + 3414 + ret = devm_request_threaded_irq(dev, 3415 + irq, NULL, ab8500_charger_irq[i].isr, 3416 + IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 3417 + ab8500_charger_irq[i].name, di); 3418 + 3419 + if (ret != 0) { 3420 + dev_err(dev, "failed to request %s IRQ %d: %d\n" 3421 + , ab8500_charger_irq[i].name, irq, ret); 3422 + return ret; 3423 + } 3424 + dev_dbg(dev, "Requested %s IRQ %d: %d\n", 3425 + ab8500_charger_irq[i].name, irq, ret); 3426 + } 3427 + 3453 3428 /* initialize lock */ 3454 3429 spin_lock_init(&di->usb_state.usb_lock); 3455 3430 mutex_init(&di->usb_ipt_crnt_lock); ··· 3508 3419 di->ac_chg.max_out_curr = 3509 3420 di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; 3510 3421 di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; 3511 - di->ac_chg.enabled = di->bm->ac_enabled; 3422 + /* 3423 + * The AB8505 only supports USB charging. If we are not the 3424 + * AB8505, register an AC charger. 3425 + * 3426 + * TODO: if this should be opt-in, add DT properties for this. 3427 + */ 3428 + if (!is_ab8505(di->parent)) 3429 + di->ac_chg.enabled = true; 3512 3430 di->ac_chg.external = false; 3513 - 3514 - /*notifier for external charger enabling*/ 3515 - if (!di->ac_chg.enabled) 3516 - blocking_notifier_chain_register( 3517 - &charger_notifier_list, &charger_nb); 3518 3431 3519 3432 /* USB supply */ 3520 3433 /* ux500_charger sub-class */ ··· 3529 3438 di->usb_chg.max_out_curr = 3530 3439 di->bm->chg_output_curr[di->bm->n_chg_out_curr - 1]; 3531 3440 di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; 3532 - di->usb_chg.enabled = di->bm->usb_enabled; 3533 3441 di->usb_chg.external = false; 3534 3442 di->usb_state.usb_current = -1; 3535 - 3536 - /* Create a work queue for the charger */ 3537 - di->charger_wq = alloc_ordered_workqueue("ab8500_charger_wq", 3538 - WQ_MEM_RECLAIM); 3539 - if (di->charger_wq == NULL) { 3540 - dev_err(dev, "failed to create work queue\n"); 3541 - return -ENOMEM; 3542 - } 3543 3443 3544 3444 mutex_init(&di->charger_attached_mutex); 3545 3445 ··· 3582 3500 INIT_WORK(&di->check_usb_thermal_prot_work, 3583 3501 ab8500_charger_check_usb_thermal_prot_work); 3584 3502 3585 - /* 3586 - * VDD ADC supply needs to be enabled from this driver when there 3587 - * is a charger connected to avoid erroneous BTEMP_HIGH/LOW 3588 - * interrupts during charging 3589 - */ 3590 - di->regu = devm_regulator_get(dev, "vddadc"); 3591 - if (IS_ERR(di->regu)) { 3592 - ret = PTR_ERR(di->regu); 3593 - dev_err(dev, "failed to get vddadc regulator\n"); 3594 - goto free_charger_wq; 3595 - } 3596 - 3597 3503 3598 3504 /* Initialize OVV, and other registers */ 3599 3505 ret = ab8500_charger_init_hw_registers(di); 3600 3506 if (ret) { 3601 3507 dev_err(dev, "failed to initialize ABB registers\n"); 3602 - goto free_charger_wq; 3508 + return ret; 3603 3509 } 3604 3510 3605 3511 /* Register AC charger class */ 3606 3512 if (di->ac_chg.enabled) { 3607 - di->ac_chg.psy = power_supply_register(dev, 3513 + di->ac_chg.psy = devm_power_supply_register(dev, 3608 3514 &ab8500_ac_chg_desc, 3609 3515 &ac_psy_cfg); 3610 3516 if (IS_ERR(di->ac_chg.psy)) { 3611 3517 dev_err(dev, "failed to register AC charger\n"); 3612 - ret = PTR_ERR(di->ac_chg.psy); 3613 - goto free_charger_wq; 3518 + return PTR_ERR(di->ac_chg.psy); 3614 3519 } 3615 3520 } 3616 3521 3617 3522 /* Register USB charger class */ 3618 - if (di->usb_chg.enabled) { 3619 - di->usb_chg.psy = power_supply_register(dev, 3620 - &ab8500_usb_chg_desc, 3621 - &usb_psy_cfg); 3622 - if (IS_ERR(di->usb_chg.psy)) { 3623 - dev_err(dev, "failed to register USB charger\n"); 3624 - ret = PTR_ERR(di->usb_chg.psy); 3625 - goto free_ac; 3626 - } 3627 - } 3628 - 3629 - di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); 3630 - if (IS_ERR_OR_NULL(di->usb_phy)) { 3631 - dev_err(dev, "failed to get usb transceiver\n"); 3632 - ret = -EINVAL; 3633 - goto free_usb; 3634 - } 3635 - di->nb.notifier_call = ab8500_charger_usb_notifier_call; 3636 - ret = usb_register_notifier(di->usb_phy, &di->nb); 3637 - if (ret) { 3638 - dev_err(dev, "failed to register usb notifier\n"); 3639 - goto put_usb_phy; 3523 + di->usb_chg.psy = devm_power_supply_register(dev, 3524 + &ab8500_usb_chg_desc, 3525 + &usb_psy_cfg); 3526 + if (IS_ERR(di->usb_chg.psy)) { 3527 + dev_err(dev, "failed to register USB charger\n"); 3528 + return PTR_ERR(di->usb_chg.psy); 3640 3529 } 3641 3530 3642 3531 /* Identify the connected charger types during startup */ ··· 3619 3566 sysfs_notify(&di->ac_chg.psy->dev.kobj, NULL, "present"); 3620 3567 } 3621 3568 3622 - if (charger_status & USB_PW_CONN) { 3623 - di->vbus_detected = true; 3624 - di->vbus_detected_start = true; 3625 - queue_work(di->charger_wq, 3626 - &di->detect_usb_type_work); 3627 - } 3628 - 3629 - /* Register interrupts */ 3630 - for (i = 0; i < ARRAY_SIZE(ab8500_charger_irq); i++) { 3631 - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); 3632 - if (irq < 0) { 3633 - ret = irq; 3634 - goto free_irq; 3635 - } 3636 - 3637 - ret = request_threaded_irq(irq, NULL, ab8500_charger_irq[i].isr, 3638 - IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 3639 - ab8500_charger_irq[i].name, di); 3640 - 3641 - if (ret != 0) { 3642 - dev_err(dev, "failed to request %s IRQ %d: %d\n" 3643 - , ab8500_charger_irq[i].name, irq, ret); 3644 - goto free_irq; 3645 - } 3646 - dev_dbg(dev, "Requested %s IRQ %d: %d\n", 3647 - ab8500_charger_irq[i].name, irq, ret); 3648 - } 3649 - 3650 3569 platform_set_drvdata(pdev, di); 3651 3570 3652 - mutex_lock(&di->charger_attached_mutex); 3571 + /* Create something that will match the subdrivers when we bind */ 3572 + for (i = 0; i < ARRAY_SIZE(ab8500_charger_component_drivers); i++) { 3573 + struct device_driver *drv = &ab8500_charger_component_drivers[i]->driver; 3574 + struct device *p = NULL, *d; 3653 3575 3654 - ch_stat = ab8500_charger_detect_chargers(di, false); 3655 - 3656 - if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { 3657 - if (is_ab8500(di->parent)) 3658 - queue_delayed_work(di->charger_wq, 3659 - &di->ac_charger_attached_work, 3660 - HZ); 3576 + while ((d = platform_find_device_by_driver(p, drv))) { 3577 + put_device(p); 3578 + component_match_add(dev, &match, 3579 + ab8500_charger_compare_dev, d); 3580 + p = d; 3581 + } 3582 + put_device(p); 3661 3583 } 3662 - if ((ch_stat & USB_PW_CONN) == USB_PW_CONN) { 3663 - if (is_ab8500(di->parent)) 3664 - queue_delayed_work(di->charger_wq, 3665 - &di->usb_charger_attached_work, 3666 - HZ); 3584 + if (!match) { 3585 + dev_err(dev, "no matching components\n"); 3586 + return -ENODEV; 3587 + } 3588 + if (IS_ERR(match)) { 3589 + dev_err(dev, "could not create component match\n"); 3590 + return PTR_ERR(match); 3667 3591 } 3668 3592 3669 - mutex_unlock(&di->charger_attached_mutex); 3593 + /* Notifier for external charger enabling */ 3594 + if (!di->ac_chg.enabled) 3595 + blocking_notifier_chain_register( 3596 + &charger_notifier_list, &charger_nb); 3670 3597 3671 - return ret; 3672 3598 3673 - free_irq: 3599 + di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); 3600 + if (IS_ERR_OR_NULL(di->usb_phy)) { 3601 + dev_err(dev, "failed to get usb transceiver\n"); 3602 + ret = -EINVAL; 3603 + goto out_charger_notifier; 3604 + } 3605 + di->nb.notifier_call = ab8500_charger_usb_notifier_call; 3606 + ret = usb_register_notifier(di->usb_phy, &di->nb); 3607 + if (ret) { 3608 + dev_err(dev, "failed to register usb notifier\n"); 3609 + goto put_usb_phy; 3610 + } 3611 + 3612 + 3613 + ret = component_master_add_with_match(&pdev->dev, 3614 + &ab8500_charger_comp_ops, 3615 + match); 3616 + if (ret) { 3617 + dev_err(dev, "failed to add component master\n"); 3618 + goto free_notifier; 3619 + } 3620 + 3621 + return 0; 3622 + 3623 + free_notifier: 3674 3624 usb_unregister_notifier(di->usb_phy, &di->nb); 3675 - 3676 - /* We also have to free all successfully registered irqs */ 3677 - for (i = i - 1; i >= 0; i--) { 3678 - irq = platform_get_irq_byname(pdev, ab8500_charger_irq[i].name); 3679 - free_irq(irq, di); 3680 - } 3681 3625 put_usb_phy: 3682 3626 usb_put_phy(di->usb_phy); 3683 - free_usb: 3684 - if (di->usb_chg.enabled) 3685 - power_supply_unregister(di->usb_chg.psy); 3686 - free_ac: 3687 - if (di->ac_chg.enabled) 3688 - power_supply_unregister(di->ac_chg.psy); 3689 - free_charger_wq: 3690 - destroy_workqueue(di->charger_wq); 3627 + out_charger_notifier: 3628 + if (!di->ac_chg.enabled) 3629 + blocking_notifier_chain_unregister( 3630 + &charger_notifier_list, &charger_nb); 3691 3631 return ret; 3632 + } 3633 + 3634 + static int ab8500_charger_remove(struct platform_device *pdev) 3635 + { 3636 + struct ab8500_charger *di = platform_get_drvdata(pdev); 3637 + 3638 + component_master_del(&pdev->dev, &ab8500_charger_comp_ops); 3639 + 3640 + usb_unregister_notifier(di->usb_phy, &di->nb); 3641 + usb_put_phy(di->usb_phy); 3642 + if (!di->ac_chg.enabled) 3643 + blocking_notifier_chain_unregister( 3644 + &charger_notifier_list, &charger_nb); 3645 + 3646 + return 0; 3692 3647 } 3693 3648 3694 3649 static SIMPLE_DEV_PM_OPS(ab8500_charger_pm_ops, ab8500_charger_suspend, ab8500_charger_resume); ··· 3705 3644 { .compatible = "stericsson,ab8500-charger", }, 3706 3645 { }, 3707 3646 }; 3647 + MODULE_DEVICE_TABLE(of, ab8500_charger_match); 3708 3648 3709 3649 static struct platform_driver ab8500_charger_driver = { 3710 3650 .probe = ab8500_charger_probe, ··· 3719 3657 3720 3658 static int __init ab8500_charger_init(void) 3721 3659 { 3660 + int ret; 3661 + 3662 + ret = platform_register_drivers(ab8500_charger_component_drivers, 3663 + ARRAY_SIZE(ab8500_charger_component_drivers)); 3664 + if (ret) 3665 + return ret; 3666 + 3722 3667 return platform_driver_register(&ab8500_charger_driver); 3723 3668 } 3724 3669 3725 3670 static void __exit ab8500_charger_exit(void) 3726 3671 { 3672 + platform_unregister_drivers(ab8500_charger_component_drivers, 3673 + ARRAY_SIZE(ab8500_charger_component_drivers)); 3727 3674 platform_driver_unregister(&ab8500_charger_driver); 3728 3675 } 3729 3676 3730 - subsys_initcall_sync(ab8500_charger_init); 3677 + module_init(ab8500_charger_init); 3731 3678 module_exit(ab8500_charger_exit); 3732 3679 3733 3680 MODULE_LICENSE("GPL v2");
+66 -79
drivers/power/supply/ab8500_fg.c
··· 17 17 18 18 #include <linux/init.h> 19 19 #include <linux/module.h> 20 + #include <linux/component.h> 20 21 #include <linux/device.h> 21 22 #include <linux/interrupt.h> 22 23 #include <linux/platform_device.h> ··· 60 59 ((y1) + ((((y2) - (y1)) * ((x) - (x1))) / ((x2) - (x1)))); 61 60 62 61 /** 63 - * struct ab8500_fg_interrupts - ab8500 fg interupts 62 + * struct ab8500_fg_interrupts - ab8500 fg interrupts 64 63 * @name: name of the interrupt 65 64 * @isr function pointer to the isr 66 65 */ ··· 2981 2980 return 0; 2982 2981 } 2983 2982 2984 - static int ab8500_fg_remove(struct platform_device *pdev) 2985 - { 2986 - int ret = 0; 2987 - struct ab8500_fg *di = platform_get_drvdata(pdev); 2988 - 2989 - list_del(&di->node); 2990 - 2991 - /* Disable coulomb counter */ 2992 - ret = ab8500_fg_coulomb_counter(di, false); 2993 - if (ret) 2994 - dev_err(di->dev, "failed to disable coulomb counter\n"); 2995 - 2996 - destroy_workqueue(di->fg_wq); 2997 - ab8500_fg_sysfs_exit(di); 2998 - 2999 - flush_scheduled_work(); 3000 - ab8500_fg_sysfs_psy_remove_attrs(di); 3001 - power_supply_unregister(di->fg_psy); 3002 - return ret; 3003 - } 3004 - 3005 2983 /* ab8500 fg driver interrupts and their respective isr */ 3006 2984 static struct ab8500_fg_interrupts ab8500_fg_irq[] = { 3007 2985 {"NCONV_ACCU", ab8500_fg_cc_convend_handler}, ··· 3004 3024 .external_power_changed = ab8500_fg_external_power_changed, 3005 3025 }; 3006 3026 3027 + static int ab8500_fg_bind(struct device *dev, struct device *master, 3028 + void *data) 3029 + { 3030 + struct ab8500_fg *di = dev_get_drvdata(dev); 3031 + 3032 + /* Create a work queue for running the FG algorithm */ 3033 + di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); 3034 + if (di->fg_wq == NULL) { 3035 + dev_err(dev, "failed to create work queue\n"); 3036 + return -ENOMEM; 3037 + } 3038 + 3039 + /* Start the coulomb counter */ 3040 + ab8500_fg_coulomb_counter(di, true); 3041 + /* Run the FG algorithm */ 3042 + queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); 3043 + 3044 + return 0; 3045 + } 3046 + 3047 + static void ab8500_fg_unbind(struct device *dev, struct device *master, 3048 + void *data) 3049 + { 3050 + struct ab8500_fg *di = dev_get_drvdata(dev); 3051 + int ret; 3052 + 3053 + /* Disable coulomb counter */ 3054 + ret = ab8500_fg_coulomb_counter(di, false); 3055 + if (ret) 3056 + dev_err(dev, "failed to disable coulomb counter\n"); 3057 + 3058 + destroy_workqueue(di->fg_wq); 3059 + flush_scheduled_work(); 3060 + } 3061 + 3062 + static const struct component_ops ab8500_fg_component_ops = { 3063 + .bind = ab8500_fg_bind, 3064 + .unbind = ab8500_fg_unbind, 3065 + }; 3066 + 3007 3067 static int ab8500_fg_probe(struct platform_device *pdev) 3008 3068 { 3009 - struct device_node *np = pdev->dev.of_node; 3010 - struct power_supply_config psy_cfg = {}; 3011 3069 struct device *dev = &pdev->dev; 3070 + struct power_supply_config psy_cfg = {}; 3012 3071 struct ab8500_fg *di; 3013 3072 int i, irq; 3014 3073 int ret = 0; ··· 3057 3038 return -ENOMEM; 3058 3039 3059 3040 di->bm = &ab8500_bm_data; 3060 - 3061 - ret = ab8500_bm_of_probe(dev, np, di->bm); 3062 - if (ret) { 3063 - dev_err(dev, "failed to get battery information\n"); 3064 - return ret; 3065 - } 3066 3041 3067 3042 mutex_init(&di->cc_lock); 3068 3043 ··· 3086 3073 3087 3074 ab8500_fg_charge_state_to(di, AB8500_FG_CHARGE_INIT); 3088 3075 ab8500_fg_discharge_state_to(di, AB8500_FG_DISCHARGE_INIT); 3089 - 3090 - /* Create a work queue for running the FG algorithm */ 3091 - di->fg_wq = alloc_ordered_workqueue("ab8500_fg_wq", WQ_MEM_RECLAIM); 3092 - if (di->fg_wq == NULL) { 3093 - dev_err(dev, "failed to create work queue\n"); 3094 - return -ENOMEM; 3095 - } 3096 3076 3097 3077 /* Init work for running the fg algorithm instantly */ 3098 3078 INIT_WORK(&di->fg_work, ab8500_fg_instant_work); ··· 3119 3113 ret = ab8500_fg_init_hw_registers(di); 3120 3114 if (ret) { 3121 3115 dev_err(dev, "failed to initialize registers\n"); 3122 - goto free_inst_curr_wq; 3116 + return ret; 3123 3117 } 3124 3118 3125 3119 /* Consider battery unknown until we're informed otherwise */ ··· 3127 3121 di->flags.batt_id_received = false; 3128 3122 3129 3123 /* Register FG power supply class */ 3130 - di->fg_psy = power_supply_register(dev, &ab8500_fg_desc, &psy_cfg); 3124 + di->fg_psy = devm_power_supply_register(dev, &ab8500_fg_desc, &psy_cfg); 3131 3125 if (IS_ERR(di->fg_psy)) { 3132 3126 dev_err(dev, "failed to register FG psy\n"); 3133 - ret = PTR_ERR(di->fg_psy); 3134 - goto free_inst_curr_wq; 3127 + return PTR_ERR(di->fg_psy); 3135 3128 } 3136 3129 3137 3130 di->fg_samples = SEC_TO_SAMPLE(di->bm->fg_params->init_timer); 3138 - ab8500_fg_coulomb_counter(di, true); 3139 3131 3140 3132 /* 3141 3133 * Initialize completion used to notify completion and start ··· 3145 3141 /* Register primary interrupt handlers */ 3146 3142 for (i = 0; i < ARRAY_SIZE(ab8500_fg_irq); i++) { 3147 3143 irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); 3148 - if (irq < 0) { 3149 - ret = irq; 3150 - goto free_irq; 3151 - } 3144 + if (irq < 0) 3145 + return irq; 3152 3146 3153 - ret = request_threaded_irq(irq, NULL, ab8500_fg_irq[i].isr, 3147 + ret = devm_request_threaded_irq(dev, irq, NULL, 3148 + ab8500_fg_irq[i].isr, 3154 3149 IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, 3155 3150 ab8500_fg_irq[i].name, di); 3156 3151 3157 3152 if (ret != 0) { 3158 3153 dev_err(dev, "failed to request %s IRQ %d: %d\n", 3159 3154 ab8500_fg_irq[i].name, irq, ret); 3160 - goto free_irq; 3155 + return ret; 3161 3156 } 3162 3157 dev_dbg(dev, "Requested %s IRQ %d: %d\n", 3163 3158 ab8500_fg_irq[i].name, irq, ret); ··· 3171 3168 ret = ab8500_fg_sysfs_init(di); 3172 3169 if (ret) { 3173 3170 dev_err(dev, "failed to create sysfs entry\n"); 3174 - goto free_irq; 3171 + return ret; 3175 3172 } 3176 3173 3177 3174 ret = ab8500_fg_sysfs_psy_create_attrs(di); 3178 3175 if (ret) { 3179 3176 dev_err(dev, "failed to create FG psy\n"); 3180 3177 ab8500_fg_sysfs_exit(di); 3181 - goto free_irq; 3178 + return ret; 3182 3179 } 3183 3180 3184 3181 /* Calibrate the fg first time */ ··· 3188 3185 /* Use room temp as default value until we get an update from driver. */ 3189 3186 di->bat_temp = 210; 3190 3187 3191 - /* Run the FG algorithm */ 3192 - queue_delayed_work(di->fg_wq, &di->fg_periodic_work, 0); 3193 - 3194 3188 list_add_tail(&di->node, &ab8500_fg_list); 3195 3189 3196 - return ret; 3190 + return component_add(dev, &ab8500_fg_component_ops); 3191 + } 3197 3192 3198 - free_irq: 3199 - /* We also have to free all registered irqs */ 3200 - while (--i >= 0) { 3201 - /* Last assignment of i from primary interrupt handlers */ 3202 - irq = platform_get_irq_byname(pdev, ab8500_fg_irq[i].name); 3203 - free_irq(irq, di); 3204 - } 3193 + static int ab8500_fg_remove(struct platform_device *pdev) 3194 + { 3195 + int ret = 0; 3196 + struct ab8500_fg *di = platform_get_drvdata(pdev); 3205 3197 3206 - power_supply_unregister(di->fg_psy); 3207 - free_inst_curr_wq: 3208 - destroy_workqueue(di->fg_wq); 3198 + component_del(&pdev->dev, &ab8500_fg_component_ops); 3199 + list_del(&di->node); 3200 + ab8500_fg_sysfs_exit(di); 3201 + ab8500_fg_sysfs_psy_remove_attrs(di); 3202 + 3209 3203 return ret; 3210 3204 } 3211 3205 ··· 3212 3212 { .compatible = "stericsson,ab8500-fg", }, 3213 3213 { }, 3214 3214 }; 3215 + MODULE_DEVICE_TABLE(of, ab8500_fg_match); 3215 3216 3216 - static struct platform_driver ab8500_fg_driver = { 3217 + struct platform_driver ab8500_fg_driver = { 3217 3218 .probe = ab8500_fg_probe, 3218 3219 .remove = ab8500_fg_remove, 3219 3220 .driver = { ··· 3223 3222 .pm = &ab8500_fg_pm_ops, 3224 3223 }, 3225 3224 }; 3226 - 3227 - static int __init ab8500_fg_init(void) 3228 - { 3229 - return platform_driver_register(&ab8500_fg_driver); 3230 - } 3231 - 3232 - static void __exit ab8500_fg_exit(void) 3233 - { 3234 - platform_driver_unregister(&ab8500_fg_driver); 3235 - } 3236 - 3237 - subsys_initcall_sync(ab8500_fg_init); 3238 - module_exit(ab8500_fg_exit); 3239 - 3240 3225 MODULE_LICENSE("GPL v2"); 3241 3226 MODULE_AUTHOR("Johan Palsson, Karl Komierowski"); 3242 3227 MODULE_ALIAS("platform:ab8500-fg");
+64 -59
drivers/power/supply/abx500_chargalg.c
··· 15 15 #include <linux/init.h> 16 16 #include <linux/module.h> 17 17 #include <linux/device.h> 18 + #include <linux/component.h> 18 19 #include <linux/hrtimer.h> 19 20 #include <linux/interrupt.h> 20 21 #include <linux/delay.h> ··· 1944 1943 return 0; 1945 1944 } 1946 1945 1947 - static int abx500_chargalg_remove(struct platform_device *pdev) 1948 - { 1949 - struct abx500_chargalg *di = platform_get_drvdata(pdev); 1950 - 1951 - /* sysfs interface to enable/disbale charging from user space */ 1952 - abx500_chargalg_sysfs_exit(di); 1953 - 1954 - hrtimer_cancel(&di->safety_timer); 1955 - hrtimer_cancel(&di->maintenance_timer); 1956 - 1957 - cancel_delayed_work_sync(&di->chargalg_periodic_work); 1958 - cancel_delayed_work_sync(&di->chargalg_wd_work); 1959 - cancel_work_sync(&di->chargalg_work); 1960 - 1961 - /* Delete the work queue */ 1962 - destroy_workqueue(di->chargalg_wq); 1963 - 1964 - power_supply_unregister(di->chargalg_psy); 1965 - 1966 - return 0; 1967 - } 1968 - 1969 1946 static char *supply_interface[] = { 1970 1947 "ab8500_fg", 1971 1948 }; ··· 1957 1978 .external_power_changed = abx500_chargalg_external_power_changed, 1958 1979 }; 1959 1980 1981 + static int abx500_chargalg_bind(struct device *dev, struct device *master, 1982 + void *data) 1983 + { 1984 + struct abx500_chargalg *di = dev_get_drvdata(dev); 1985 + 1986 + /* Create a work queue for the chargalg */ 1987 + di->chargalg_wq = alloc_ordered_workqueue("abx500_chargalg_wq", 1988 + WQ_MEM_RECLAIM); 1989 + if (di->chargalg_wq == NULL) { 1990 + dev_err(di->dev, "failed to create work queue\n"); 1991 + return -ENOMEM; 1992 + } 1993 + 1994 + /* Run the charging algorithm */ 1995 + queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0); 1996 + 1997 + return 0; 1998 + } 1999 + 2000 + static void abx500_chargalg_unbind(struct device *dev, struct device *master, 2001 + void *data) 2002 + { 2003 + struct abx500_chargalg *di = dev_get_drvdata(dev); 2004 + 2005 + /* Stop all timers and work */ 2006 + hrtimer_cancel(&di->safety_timer); 2007 + hrtimer_cancel(&di->maintenance_timer); 2008 + 2009 + cancel_delayed_work_sync(&di->chargalg_periodic_work); 2010 + cancel_delayed_work_sync(&di->chargalg_wd_work); 2011 + cancel_work_sync(&di->chargalg_work); 2012 + 2013 + /* Delete the work queue */ 2014 + destroy_workqueue(di->chargalg_wq); 2015 + flush_scheduled_work(); 2016 + } 2017 + 2018 + static const struct component_ops abx500_chargalg_component_ops = { 2019 + .bind = abx500_chargalg_bind, 2020 + .unbind = abx500_chargalg_unbind, 2021 + }; 2022 + 1960 2023 static int abx500_chargalg_probe(struct platform_device *pdev) 1961 2024 { 1962 - struct device_node *np = pdev->dev.of_node; 2025 + struct device *dev = &pdev->dev; 1963 2026 struct power_supply_config psy_cfg = {}; 1964 2027 struct abx500_chargalg *di; 1965 2028 int ret = 0; 1966 2029 1967 - di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL); 1968 - if (!di) { 1969 - dev_err(&pdev->dev, "%s no mem for ab8500_chargalg\n", __func__); 2030 + di = devm_kzalloc(dev, sizeof(*di), GFP_KERNEL); 2031 + if (!di) 1970 2032 return -ENOMEM; 1971 - } 1972 2033 1973 2034 di->bm = &ab8500_bm_data; 1974 2035 1975 - ret = ab8500_bm_of_probe(&pdev->dev, np, di->bm); 1976 - if (ret) { 1977 - dev_err(&pdev->dev, "failed to get battery information\n"); 1978 - return ret; 1979 - } 1980 - 1981 2036 /* get device struct and parent */ 1982 - di->dev = &pdev->dev; 2037 + di->dev = dev; 1983 2038 di->parent = dev_get_drvdata(pdev->dev.parent); 1984 2039 1985 2040 psy_cfg.supplied_to = supply_interface; ··· 2029 2016 di->maintenance_timer.function = 2030 2017 abx500_chargalg_maintenance_timer_expired; 2031 2018 2032 - /* Create a work queue for the chargalg */ 2033 - di->chargalg_wq = alloc_ordered_workqueue("abx500_chargalg_wq", 2034 - WQ_MEM_RECLAIM); 2035 - if (di->chargalg_wq == NULL) { 2036 - dev_err(di->dev, "failed to create work queue\n"); 2037 - return -ENOMEM; 2038 - } 2039 - 2040 2019 /* Init work for chargalg */ 2041 2020 INIT_DEFERRABLE_WORK(&di->chargalg_periodic_work, 2042 2021 abx500_chargalg_periodic_work); ··· 2042 2037 di->chg_info.prev_conn_chg = -1; 2043 2038 2044 2039 /* Register chargalg power supply class */ 2045 - di->chargalg_psy = power_supply_register(di->dev, &abx500_chargalg_desc, 2040 + di->chargalg_psy = devm_power_supply_register(di->dev, 2041 + &abx500_chargalg_desc, 2046 2042 &psy_cfg); 2047 2043 if (IS_ERR(di->chargalg_psy)) { 2048 2044 dev_err(di->dev, "failed to register chargalg psy\n"); 2049 - ret = PTR_ERR(di->chargalg_psy); 2050 - goto free_chargalg_wq; 2045 + return PTR_ERR(di->chargalg_psy); 2051 2046 } 2052 2047 2053 2048 platform_set_drvdata(pdev, di); ··· 2056 2051 ret = abx500_chargalg_sysfs_init(di); 2057 2052 if (ret) { 2058 2053 dev_err(di->dev, "failed to create sysfs entry\n"); 2059 - goto free_psy; 2054 + return ret; 2060 2055 } 2061 2056 di->curr_status.curr_step = CHARGALG_CURR_STEP_HIGH; 2062 2057 2063 - /* Run the charging algorithm */ 2064 - queue_delayed_work(di->chargalg_wq, &di->chargalg_periodic_work, 0); 2065 - 2066 2058 dev_info(di->dev, "probe success\n"); 2067 - return ret; 2059 + return component_add(dev, &abx500_chargalg_component_ops); 2060 + } 2068 2061 2069 - free_psy: 2070 - power_supply_unregister(di->chargalg_psy); 2071 - free_chargalg_wq: 2072 - destroy_workqueue(di->chargalg_wq); 2073 - return ret; 2062 + static int abx500_chargalg_remove(struct platform_device *pdev) 2063 + { 2064 + struct abx500_chargalg *di = platform_get_drvdata(pdev); 2065 + 2066 + component_del(&pdev->dev, &abx500_chargalg_component_ops); 2067 + 2068 + /* sysfs interface to enable/disable charging from user space */ 2069 + abx500_chargalg_sysfs_exit(di); 2070 + 2071 + return 0; 2074 2072 } 2075 2073 2076 2074 static SIMPLE_DEV_PM_OPS(abx500_chargalg_pm_ops, abx500_chargalg_suspend, abx500_chargalg_resume); ··· 2083 2075 { }, 2084 2076 }; 2085 2077 2086 - static struct platform_driver abx500_chargalg_driver = { 2078 + struct platform_driver abx500_chargalg_driver = { 2087 2079 .probe = abx500_chargalg_probe, 2088 2080 .remove = abx500_chargalg_remove, 2089 2081 .driver = { ··· 2092 2084 .pm = &abx500_chargalg_pm_ops, 2093 2085 }, 2094 2086 }; 2095 - 2096 - module_platform_driver(abx500_chargalg_driver); 2097 - 2098 2087 MODULE_LICENSE("GPL v2"); 2099 2088 MODULE_AUTHOR("Johan Palsson, Karl Komierowski"); 2100 2089 MODULE_ALIAS("platform:abx500-chargalg");
+14 -1
drivers/power/supply/axp20x_battery.c
··· 40 40 #define AXP209_FG_PERCENT GENMASK(6, 0) 41 41 #define AXP22X_FG_VALID BIT(7) 42 42 43 + #define AXP20X_CHRG_CTRL1_ENABLE BIT(7) 43 44 #define AXP20X_CHRG_CTRL1_TGT_VOLT GENMASK(6, 5) 44 45 #define AXP20X_CHRG_CTRL1_TGT_4_1V (0 << 5) 45 46 #define AXP20X_CHRG_CTRL1_TGT_4_15V (1 << 5) ··· 469 468 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 470 469 return axp20x_set_max_constant_charge_current(axp20x_batt, 471 470 val->intval); 471 + case POWER_SUPPLY_PROP_STATUS: 472 + switch (val->intval) { 473 + case POWER_SUPPLY_STATUS_CHARGING: 474 + return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, 475 + AXP20X_CHRG_CTRL1_ENABLE, AXP20X_CHRG_CTRL1_ENABLE); 472 476 477 + case POWER_SUPPLY_STATUS_DISCHARGING: 478 + case POWER_SUPPLY_STATUS_NOT_CHARGING: 479 + return regmap_update_bits(axp20x_batt->regmap, AXP20X_CHRG_CTRL1, 480 + AXP20X_CHRG_CTRL1_ENABLE, 0); 481 + } 482 + fallthrough; 473 483 default: 474 484 return -EINVAL; 475 485 } ··· 503 491 static int axp20x_battery_prop_writeable(struct power_supply *psy, 504 492 enum power_supply_property psp) 505 493 { 506 - return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || 494 + return psp == POWER_SUPPLY_PROP_STATUS || 495 + psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || 507 496 psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || 508 497 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || 509 498 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
+12 -14
drivers/power/supply/axp288_fuel_gauge.c
··· 142 142 143 143 for (i = 0; i < NR_RETRY_CNT; i++) { 144 144 ret = regmap_read(info->regmap, reg, &val); 145 - if (ret == -EBUSY) 146 - continue; 147 - else 145 + if (ret != -EBUSY) 148 146 break; 149 147 } 150 148 ··· 674 676 * detection reports one despite it not being there. 675 677 * Please keep this listed sorted alphabetically. 676 678 */ 677 - static const struct dmi_system_id axp288_fuel_gauge_blacklist[] = { 679 + static const struct dmi_system_id axp288_no_battery_list[] = { 678 680 { 679 681 /* ACEPC T8 Cherry Trail Z8350 mini PC */ 680 682 .matches = { ··· 721 723 DMI_MATCH(DMI_PRODUCT_NAME, "MEEGOPAD T02"), 722 724 }, 723 725 }, 724 - { 725 - /* Meegopad T08 */ 726 - .matches = { 727 - DMI_MATCH(DMI_SYS_VENDOR, "Default string"), 728 - DMI_MATCH(DMI_BOARD_VENDOR, "To be filled by OEM."), 729 - DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"), 730 - DMI_MATCH(DMI_BOARD_VERSION, "V1.1"), 731 - }, 732 - }, 733 726 { /* Mele PCG03 Mini PC */ 734 727 .matches = { 735 728 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"), ··· 733 744 DMI_MATCH(DMI_SYS_VENDOR, "MINIX"), 734 745 DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), 735 746 } 747 + }, 748 + { 749 + /* Various Ace PC/Meegopad/MinisForum/Wintel Mini-PCs/HDMI-sticks */ 750 + .matches = { 751 + DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"), 752 + DMI_MATCH(DMI_CHASSIS_TYPE, "3"), 753 + DMI_MATCH(DMI_BIOS_VENDOR, "American Megatrends Inc."), 754 + DMI_MATCH(DMI_BIOS_VERSION, "5.11"), 755 + }, 736 756 }, 737 757 {} 738 758 }; ··· 762 764 }; 763 765 unsigned int val; 764 766 765 - if (dmi_check_system(axp288_fuel_gauge_blacklist)) 767 + if (dmi_check_system(axp288_no_battery_list)) 766 768 return -ENODEV; 767 769 768 770 /*
-710
drivers/power/supply/bd70528-charger.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-or-later 2 - // 3 - // Copyright (C) 2018 ROHM Semiconductors 4 - // 5 - // power-supply driver for ROHM BD70528 PMIC 6 - 7 - /* 8 - * BD70528 charger HW state machine. 9 - * 10 - * The thermal shutdown state is not drawn. From any other state but 11 - * battery error and suspend it is possible to go to TSD/TMP states 12 - * if temperature is out of bounds. 13 - * 14 - * CHG_RST = H 15 - * or CHG_EN=L 16 - * or (DCIN2_UVLO=L && DCIN1_UVLO=L) 17 - * or (DCIN2_OVLO=H & DCIN1_UVKLO=L) 18 - * 19 - * +--------------+ +--------------+ 20 - * | | | | 21 - * | Any state +-------> | Suspend | 22 - * | | | | 23 - * +--------------+ +------+-------+ 24 - * | 25 - * CHG_EN = H && BAT_DET = H && | 26 - * No errors (temp, bat_ov, UVLO, | 27 - * OVLO...) | 28 - * | 29 - * BAT_OV or +---------v----------+ 30 - * (DBAT && TTRI) | | 31 - * +-----------------+ Trickle Charge | <---------------+ 32 - * | | | | 33 - * | +-------+------------+ | 34 - * | | | 35 - * | | ^ | 36 - * | V_BAT > VTRI_TH | | VBAT < VTRI_TH - 50mV | 37 - * | | | | 38 - * | v | | 39 - * | | | 40 - * | BAT_OV or +----------+----+ | 41 - * | (DBAT && TFST) | | | 42 - * | +----------------+ Fast Charge | | 43 - * | | | | | 44 - * v v +----+----------+ | 45 - * | | 46 - *+----------------+ ILIM_DET=L | ^ ILIM_DET | 47 - *| | & CV_DET=H | | or CV_DET=L | 48 - *| Battery Error | & VBAT > | | or VBAT < VRECHG_TH | 49 - *| | VRECHG_TH | | or IBAT > IFST/x | 50 - *+----------------+ & IBAT < | | | 51 - * IFST/x v | | 52 - * ^ | | 53 - * | +---------+-+ | 54 - * | | | | 55 - * +-------------------+ Top OFF | | 56 - * BAT_OV = H or | | | 57 - * (DBAT && TFST) +-----+-----+ | 58 - * | | 59 - * Stay top-off for 15s | | 60 - * v | 61 - * | 62 - * +--------+ | 63 - * | | | 64 - * | Done +-------------------------+ 65 - * | | 66 - * +--------+ VBAT < VRECHG_TH 67 - */ 68 - 69 - #include <linux/kernel.h> 70 - #include <linux/interrupt.h> 71 - #include <linux/mfd/rohm-bd70528.h> 72 - #include <linux/module.h> 73 - #include <linux/platform_device.h> 74 - #include <linux/power_supply.h> 75 - #include <linux/linear_range.h> 76 - 77 - #define CHG_STAT_SUSPEND 0x0 78 - #define CHG_STAT_TRICKLE 0x1 79 - #define CHG_STAT_FAST 0x3 80 - #define CHG_STAT_TOPOFF 0xe 81 - #define CHG_STAT_DONE 0xf 82 - #define CHG_STAT_OTP_TRICKLE 0x10 83 - #define CHG_STAT_OTP_FAST 0x11 84 - #define CHG_STAT_OTP_DONE 0x12 85 - #define CHG_STAT_TSD_TRICKLE 0x20 86 - #define CHG_STAT_TSD_FAST 0x21 87 - #define CHG_STAT_TSD_TOPOFF 0x22 88 - #define CHG_STAT_BAT_ERR 0x7f 89 - 90 - static const char *bd70528_charger_model = "BD70528"; 91 - static const char *bd70528_charger_manufacturer = "ROHM Semiconductors"; 92 - 93 - #define BD_ERR_IRQ_HND(_name_, _wrn_) \ 94 - static irqreturn_t bd0528_##_name_##_interrupt(int irq, void *arg) \ 95 - { \ 96 - struct power_supply *psy = (struct power_supply *)arg; \ 97 - \ 98 - power_supply_changed(psy); \ 99 - dev_err(&psy->dev, (_wrn_)); \ 100 - \ 101 - return IRQ_HANDLED; \ 102 - } 103 - 104 - #define BD_INFO_IRQ_HND(_name_, _wrn_) \ 105 - static irqreturn_t bd0528_##_name_##_interrupt(int irq, void *arg) \ 106 - { \ 107 - struct power_supply *psy = (struct power_supply *)arg; \ 108 - \ 109 - power_supply_changed(psy); \ 110 - dev_dbg(&psy->dev, (_wrn_)); \ 111 - \ 112 - return IRQ_HANDLED; \ 113 - } 114 - 115 - #define BD_IRQ_HND(_name_) bd0528_##_name_##_interrupt 116 - 117 - struct bd70528_psy { 118 - struct regmap *regmap; 119 - struct device *dev; 120 - struct power_supply *psy; 121 - }; 122 - 123 - BD_ERR_IRQ_HND(BAT_OV_DET, "Battery overvoltage detected\n"); 124 - BD_ERR_IRQ_HND(DBAT_DET, "Dead battery detected\n"); 125 - BD_ERR_IRQ_HND(COLD_DET, "Battery cold\n"); 126 - BD_ERR_IRQ_HND(HOT_DET, "Battery hot\n"); 127 - BD_ERR_IRQ_HND(CHG_TSD, "Charger thermal shutdown\n"); 128 - BD_ERR_IRQ_HND(DCIN2_OV_DET, "DCIN2 overvoltage detected\n"); 129 - 130 - BD_INFO_IRQ_HND(BAT_OV_RES, "Battery voltage back to normal\n"); 131 - BD_INFO_IRQ_HND(COLD_RES, "Battery temperature back to normal\n"); 132 - BD_INFO_IRQ_HND(HOT_RES, "Battery temperature back to normal\n"); 133 - BD_INFO_IRQ_HND(BAT_RMV, "Battery removed\n"); 134 - BD_INFO_IRQ_HND(BAT_DET, "Battery detected\n"); 135 - BD_INFO_IRQ_HND(DCIN2_OV_RES, "DCIN2 voltage back to normal\n"); 136 - BD_INFO_IRQ_HND(DCIN2_RMV, "DCIN2 removed\n"); 137 - BD_INFO_IRQ_HND(DCIN2_DET, "DCIN2 detected\n"); 138 - BD_INFO_IRQ_HND(DCIN1_RMV, "DCIN1 removed\n"); 139 - BD_INFO_IRQ_HND(DCIN1_DET, "DCIN1 detected\n"); 140 - 141 - struct irq_name_pair { 142 - const char *n; 143 - irqreturn_t (*h)(int irq, void *arg); 144 - }; 145 - 146 - static int bd70528_get_irqs(struct platform_device *pdev, 147 - struct bd70528_psy *bdpsy) 148 - { 149 - int irq, i, ret; 150 - unsigned int mask; 151 - static const struct irq_name_pair bd70528_chg_irqs[] = { 152 - { .n = "bd70528-bat-ov-res", .h = BD_IRQ_HND(BAT_OV_RES) }, 153 - { .n = "bd70528-bat-ov-det", .h = BD_IRQ_HND(BAT_OV_DET) }, 154 - { .n = "bd70528-bat-dead", .h = BD_IRQ_HND(DBAT_DET) }, 155 - { .n = "bd70528-bat-warmed", .h = BD_IRQ_HND(COLD_RES) }, 156 - { .n = "bd70528-bat-cold", .h = BD_IRQ_HND(COLD_DET) }, 157 - { .n = "bd70528-bat-cooled", .h = BD_IRQ_HND(HOT_RES) }, 158 - { .n = "bd70528-bat-hot", .h = BD_IRQ_HND(HOT_DET) }, 159 - { .n = "bd70528-chg-tshd", .h = BD_IRQ_HND(CHG_TSD) }, 160 - { .n = "bd70528-bat-removed", .h = BD_IRQ_HND(BAT_RMV) }, 161 - { .n = "bd70528-bat-detected", .h = BD_IRQ_HND(BAT_DET) }, 162 - { .n = "bd70528-dcin2-ov-res", .h = BD_IRQ_HND(DCIN2_OV_RES) }, 163 - { .n = "bd70528-dcin2-ov-det", .h = BD_IRQ_HND(DCIN2_OV_DET) }, 164 - { .n = "bd70528-dcin2-removed", .h = BD_IRQ_HND(DCIN2_RMV) }, 165 - { .n = "bd70528-dcin2-detected", .h = BD_IRQ_HND(DCIN2_DET) }, 166 - { .n = "bd70528-dcin1-removed", .h = BD_IRQ_HND(DCIN1_RMV) }, 167 - { .n = "bd70528-dcin1-detected", .h = BD_IRQ_HND(DCIN1_DET) }, 168 - }; 169 - 170 - for (i = 0; i < ARRAY_SIZE(bd70528_chg_irqs); i++) { 171 - irq = platform_get_irq_byname(pdev, bd70528_chg_irqs[i].n); 172 - if (irq < 0) { 173 - dev_err(&pdev->dev, "Bad IRQ information for %s (%d)\n", 174 - bd70528_chg_irqs[i].n, irq); 175 - return irq; 176 - } 177 - ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, 178 - bd70528_chg_irqs[i].h, 179 - IRQF_ONESHOT, 180 - bd70528_chg_irqs[i].n, 181 - bdpsy->psy); 182 - 183 - if (ret) 184 - return ret; 185 - } 186 - /* 187 - * BD70528 irq controller is not touching the main mask register. 188 - * So enable the charger block interrupts at main level. We can just 189 - * leave them enabled as irq-controller should disable irqs 190 - * from sub-registers when IRQ is disabled or freed. 191 - */ 192 - mask = BD70528_REG_INT_BAT1_MASK | BD70528_REG_INT_BAT2_MASK; 193 - ret = regmap_update_bits(bdpsy->regmap, 194 - BD70528_REG_INT_MAIN_MASK, mask, 0); 195 - if (ret) 196 - dev_err(&pdev->dev, "Failed to enable charger IRQs\n"); 197 - 198 - return ret; 199 - } 200 - 201 - static int bd70528_get_charger_status(struct bd70528_psy *bdpsy, int *val) 202 - { 203 - int ret; 204 - unsigned int v; 205 - 206 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_CURR_STAT, &v); 207 - if (ret) { 208 - dev_err(bdpsy->dev, "Charger state read failure %d\n", 209 - ret); 210 - return ret; 211 - } 212 - 213 - switch (v & BD70528_MASK_CHG_STAT) { 214 - case CHG_STAT_SUSPEND: 215 - /* Maybe we should check the CHG_TTRI_EN? */ 216 - case CHG_STAT_OTP_TRICKLE: 217 - case CHG_STAT_OTP_FAST: 218 - case CHG_STAT_OTP_DONE: 219 - case CHG_STAT_TSD_TRICKLE: 220 - case CHG_STAT_TSD_FAST: 221 - case CHG_STAT_TSD_TOPOFF: 222 - case CHG_STAT_BAT_ERR: 223 - *val = POWER_SUPPLY_STATUS_NOT_CHARGING; 224 - break; 225 - case CHG_STAT_DONE: 226 - *val = POWER_SUPPLY_STATUS_FULL; 227 - break; 228 - case CHG_STAT_TRICKLE: 229 - case CHG_STAT_FAST: 230 - case CHG_STAT_TOPOFF: 231 - *val = POWER_SUPPLY_STATUS_CHARGING; 232 - break; 233 - default: 234 - *val = POWER_SUPPLY_STATUS_UNKNOWN; 235 - break; 236 - } 237 - 238 - return 0; 239 - } 240 - 241 - static int bd70528_get_charge_type(struct bd70528_psy *bdpsy, int *val) 242 - { 243 - int ret; 244 - unsigned int v; 245 - 246 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_CURR_STAT, &v); 247 - if (ret) { 248 - dev_err(bdpsy->dev, "Charger state read failure %d\n", 249 - ret); 250 - return ret; 251 - } 252 - 253 - switch (v & BD70528_MASK_CHG_STAT) { 254 - case CHG_STAT_TRICKLE: 255 - *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE; 256 - break; 257 - case CHG_STAT_FAST: 258 - case CHG_STAT_TOPOFF: 259 - *val = POWER_SUPPLY_CHARGE_TYPE_FAST; 260 - break; 261 - case CHG_STAT_DONE: 262 - case CHG_STAT_SUSPEND: 263 - /* Maybe we should check the CHG_TTRI_EN? */ 264 - case CHG_STAT_OTP_TRICKLE: 265 - case CHG_STAT_OTP_FAST: 266 - case CHG_STAT_OTP_DONE: 267 - case CHG_STAT_TSD_TRICKLE: 268 - case CHG_STAT_TSD_FAST: 269 - case CHG_STAT_TSD_TOPOFF: 270 - case CHG_STAT_BAT_ERR: 271 - *val = POWER_SUPPLY_CHARGE_TYPE_NONE; 272 - break; 273 - default: 274 - *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN; 275 - break; 276 - } 277 - 278 - return 0; 279 - } 280 - 281 - static int bd70528_get_battery_health(struct bd70528_psy *bdpsy, int *val) 282 - { 283 - int ret; 284 - unsigned int v; 285 - 286 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_BAT_STAT, &v); 287 - if (ret) { 288 - dev_err(bdpsy->dev, "Battery state read failure %d\n", 289 - ret); 290 - return ret; 291 - } 292 - /* No battery? */ 293 - if (!(v & BD70528_MASK_CHG_BAT_DETECT)) 294 - *val = POWER_SUPPLY_HEALTH_DEAD; 295 - else if (v & BD70528_MASK_CHG_BAT_OVERVOLT) 296 - *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 297 - else if (v & BD70528_MASK_CHG_BAT_TIMER) 298 - *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE; 299 - else 300 - *val = POWER_SUPPLY_HEALTH_GOOD; 301 - 302 - return 0; 303 - } 304 - 305 - static int bd70528_get_online(struct bd70528_psy *bdpsy, int *val) 306 - { 307 - int ret; 308 - unsigned int v; 309 - 310 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_IN_STAT, &v); 311 - if (ret) { 312 - dev_err(bdpsy->dev, "DC1 IN state read failure %d\n", 313 - ret); 314 - return ret; 315 - } 316 - 317 - *val = (v & BD70528_MASK_CHG_DCIN1_UVLO) ? 1 : 0; 318 - 319 - return 0; 320 - } 321 - 322 - static int bd70528_get_present(struct bd70528_psy *bdpsy, int *val) 323 - { 324 - int ret; 325 - unsigned int v; 326 - 327 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_BAT_STAT, &v); 328 - if (ret) { 329 - dev_err(bdpsy->dev, "Battery state read failure %d\n", 330 - ret); 331 - return ret; 332 - } 333 - 334 - *val = (v & BD70528_MASK_CHG_BAT_DETECT) ? 1 : 0; 335 - 336 - return 0; 337 - } 338 - 339 - static const struct linear_range current_limit_ranges[] = { 340 - { 341 - .min = 5, 342 - .step = 1, 343 - .min_sel = 0, 344 - .max_sel = 0x22, 345 - }, 346 - { 347 - .min = 40, 348 - .step = 5, 349 - .min_sel = 0x23, 350 - .max_sel = 0x26, 351 - }, 352 - { 353 - .min = 60, 354 - .step = 20, 355 - .min_sel = 0x27, 356 - .max_sel = 0x2d, 357 - }, 358 - { 359 - .min = 200, 360 - .step = 50, 361 - .min_sel = 0x2e, 362 - .max_sel = 0x34, 363 - }, 364 - { 365 - .min = 500, 366 - .step = 0, 367 - .min_sel = 0x35, 368 - .max_sel = 0x3f, 369 - }, 370 - }; 371 - 372 - /* 373 - * BD70528 would support setting and getting own charge current/ 374 - * voltage for low temperatures. The driver currently only reads 375 - * the charge current at room temperature. We do set both though. 376 - */ 377 - static const struct linear_range warm_charge_curr[] = { 378 - { 379 - .min = 10, 380 - .step = 10, 381 - .min_sel = 0, 382 - .max_sel = 0x12, 383 - }, 384 - { 385 - .min = 200, 386 - .step = 25, 387 - .min_sel = 0x13, 388 - .max_sel = 0x1f, 389 - }, 390 - }; 391 - 392 - /* 393 - * Cold charge current selectors are identical to warm charge current 394 - * selectors. The difference is that only smaller currents are available 395 - * at cold charge range. 396 - */ 397 - #define MAX_COLD_CHG_CURR_SEL 0x15 398 - #define MAX_WARM_CHG_CURR_SEL 0x1f 399 - #define MIN_CHG_CURR_SEL 0x0 400 - 401 - static int get_charge_current(struct bd70528_psy *bdpsy, int *ma) 402 - { 403 - unsigned int sel; 404 - int ret; 405 - 406 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_CHG_CURR_WARM, 407 - &sel); 408 - if (ret) { 409 - dev_err(bdpsy->dev, 410 - "Charge current reading failed (%d)\n", ret); 411 - return ret; 412 - } 413 - 414 - sel &= BD70528_MASK_CHG_CHG_CURR; 415 - 416 - ret = linear_range_get_value_array(&warm_charge_curr[0], 417 - ARRAY_SIZE(warm_charge_curr), 418 - sel, ma); 419 - if (ret) { 420 - dev_err(bdpsy->dev, 421 - "Unknown charge current value 0x%x\n", 422 - sel); 423 - } 424 - 425 - return ret; 426 - } 427 - 428 - static int get_current_limit(struct bd70528_psy *bdpsy, int *ma) 429 - { 430 - unsigned int sel; 431 - int ret; 432 - 433 - ret = regmap_read(bdpsy->regmap, BD70528_REG_CHG_DCIN_ILIM, 434 - &sel); 435 - 436 - if (ret) { 437 - dev_err(bdpsy->dev, 438 - "Input current limit reading failed (%d)\n", ret); 439 - return ret; 440 - } 441 - 442 - sel &= BD70528_MASK_CHG_DCIN_ILIM; 443 - 444 - ret = linear_range_get_value_array(&current_limit_ranges[0], 445 - ARRAY_SIZE(current_limit_ranges), 446 - sel, ma); 447 - if (ret) { 448 - /* Unspecified values mean 500 mA */ 449 - *ma = 500; 450 - } 451 - return 0; 452 - } 453 - 454 - static enum power_supply_property bd70528_charger_props[] = { 455 - POWER_SUPPLY_PROP_STATUS, 456 - POWER_SUPPLY_PROP_CHARGE_TYPE, 457 - POWER_SUPPLY_PROP_HEALTH, 458 - POWER_SUPPLY_PROP_PRESENT, 459 - POWER_SUPPLY_PROP_ONLINE, 460 - POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 461 - POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 462 - POWER_SUPPLY_PROP_MODEL_NAME, 463 - POWER_SUPPLY_PROP_MANUFACTURER, 464 - }; 465 - 466 - static int bd70528_charger_get_property(struct power_supply *psy, 467 - enum power_supply_property psp, 468 - union power_supply_propval *val) 469 - { 470 - struct bd70528_psy *bdpsy = power_supply_get_drvdata(psy); 471 - int ret = 0; 472 - 473 - switch (psp) { 474 - case POWER_SUPPLY_PROP_STATUS: 475 - return bd70528_get_charger_status(bdpsy, &val->intval); 476 - case POWER_SUPPLY_PROP_CHARGE_TYPE: 477 - return bd70528_get_charge_type(bdpsy, &val->intval); 478 - case POWER_SUPPLY_PROP_HEALTH: 479 - return bd70528_get_battery_health(bdpsy, &val->intval); 480 - case POWER_SUPPLY_PROP_PRESENT: 481 - return bd70528_get_present(bdpsy, &val->intval); 482 - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 483 - ret = get_current_limit(bdpsy, &val->intval); 484 - val->intval *= 1000; 485 - return ret; 486 - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 487 - ret = get_charge_current(bdpsy, &val->intval); 488 - val->intval *= 1000; 489 - return ret; 490 - case POWER_SUPPLY_PROP_ONLINE: 491 - return bd70528_get_online(bdpsy, &val->intval); 492 - case POWER_SUPPLY_PROP_MODEL_NAME: 493 - val->strval = bd70528_charger_model; 494 - return 0; 495 - case POWER_SUPPLY_PROP_MANUFACTURER: 496 - val->strval = bd70528_charger_manufacturer; 497 - return 0; 498 - default: 499 - break; 500 - } 501 - 502 - return -EINVAL; 503 - } 504 - 505 - static int bd70528_prop_is_writable(struct power_supply *psy, 506 - enum power_supply_property psp) 507 - { 508 - switch (psp) { 509 - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 510 - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 511 - return 1; 512 - default: 513 - break; 514 - } 515 - return 0; 516 - } 517 - 518 - static int set_charge_current(struct bd70528_psy *bdpsy, int ma) 519 - { 520 - unsigned int reg; 521 - int ret = 0, tmpret; 522 - bool found; 523 - 524 - if (ma > 500) { 525 - dev_warn(bdpsy->dev, 526 - "Requested charge current %u exceed maximum (500mA)\n", 527 - ma); 528 - reg = MAX_WARM_CHG_CURR_SEL; 529 - goto set; 530 - } 531 - if (ma < 10) { 532 - dev_err(bdpsy->dev, 533 - "Requested charge current %u smaller than min (10mA)\n", 534 - ma); 535 - reg = MIN_CHG_CURR_SEL; 536 - ret = -EINVAL; 537 - goto set; 538 - } 539 - 540 - /* 541 - * For BD70528 voltage/current limits we happily accept any value which 542 - * belongs the range. We could check if value matching the selector is 543 - * desired by computing the range min + (sel - sel_low) * range step - but 544 - * I guess it is enough if we use voltage/current which is closest (below) 545 - * the requested? 546 - */ 547 - 548 - ret = linear_range_get_selector_low_array(warm_charge_curr, 549 - ARRAY_SIZE(warm_charge_curr), 550 - ma, &reg, &found); 551 - if (ret) { 552 - dev_err(bdpsy->dev, 553 - "Unsupported charge current %u mA\n", ma); 554 - reg = MIN_CHG_CURR_SEL; 555 - goto set; 556 - } 557 - if (!found) { 558 - /* 559 - * There was a gap in supported values and we hit it. 560 - * Yet a smaller value was found so we use it. 561 - */ 562 - dev_warn(bdpsy->dev, 563 - "Unsupported charge current %u mA\n", ma); 564 - } 565 - set: 566 - 567 - tmpret = regmap_update_bits(bdpsy->regmap, 568 - BD70528_REG_CHG_CHG_CURR_WARM, 569 - BD70528_MASK_CHG_CHG_CURR, reg); 570 - if (tmpret) 571 - dev_err(bdpsy->dev, 572 - "Charge current write failure (%d)\n", tmpret); 573 - 574 - if (reg > MAX_COLD_CHG_CURR_SEL) 575 - reg = MAX_COLD_CHG_CURR_SEL; 576 - 577 - if (!tmpret) 578 - tmpret = regmap_update_bits(bdpsy->regmap, 579 - BD70528_REG_CHG_CHG_CURR_COLD, 580 - BD70528_MASK_CHG_CHG_CURR, reg); 581 - 582 - if (!ret) 583 - ret = tmpret; 584 - 585 - return ret; 586 - } 587 - 588 - #define MAX_CURR_LIMIT_SEL 0x34 589 - #define MIN_CURR_LIMIT_SEL 0x0 590 - 591 - static int set_current_limit(struct bd70528_psy *bdpsy, int ma) 592 - { 593 - unsigned int reg; 594 - int ret = 0, tmpret; 595 - bool found; 596 - 597 - if (ma > 500) { 598 - dev_warn(bdpsy->dev, 599 - "Requested current limit %u exceed maximum (500mA)\n", 600 - ma); 601 - reg = MAX_CURR_LIMIT_SEL; 602 - goto set; 603 - } 604 - if (ma < 5) { 605 - dev_err(bdpsy->dev, 606 - "Requested current limit %u smaller than min (5mA)\n", 607 - ma); 608 - reg = MIN_CURR_LIMIT_SEL; 609 - ret = -EINVAL; 610 - goto set; 611 - } 612 - 613 - ret = linear_range_get_selector_low_array(current_limit_ranges, 614 - ARRAY_SIZE(current_limit_ranges), 615 - ma, &reg, &found); 616 - if (ret) { 617 - dev_err(bdpsy->dev, "Unsupported current limit %umA\n", ma); 618 - reg = MIN_CURR_LIMIT_SEL; 619 - goto set; 620 - } 621 - if (!found) { 622 - /* 623 - * There was a gap in supported values and we hit it. 624 - * We found a smaller value from ranges and use it. 625 - * Warn user though. 626 - */ 627 - dev_warn(bdpsy->dev, "Unsupported current limit %umA\n", ma); 628 - } 629 - 630 - set: 631 - tmpret = regmap_update_bits(bdpsy->regmap, 632 - BD70528_REG_CHG_DCIN_ILIM, 633 - BD70528_MASK_CHG_DCIN_ILIM, reg); 634 - 635 - if (!ret) 636 - ret = tmpret; 637 - 638 - return ret; 639 - } 640 - 641 - static int bd70528_charger_set_property(struct power_supply *psy, 642 - enum power_supply_property psp, 643 - const union power_supply_propval *val) 644 - { 645 - struct bd70528_psy *bdpsy = power_supply_get_drvdata(psy); 646 - 647 - switch (psp) { 648 - case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 649 - return set_current_limit(bdpsy, val->intval / 1000); 650 - case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: 651 - return set_charge_current(bdpsy, val->intval / 1000); 652 - default: 653 - break; 654 - } 655 - return -EINVAL; 656 - } 657 - 658 - static const struct power_supply_desc bd70528_charger_desc = { 659 - .name = "bd70528-charger", 660 - .type = POWER_SUPPLY_TYPE_MAINS, 661 - .properties = bd70528_charger_props, 662 - .num_properties = ARRAY_SIZE(bd70528_charger_props), 663 - .get_property = bd70528_charger_get_property, 664 - .set_property = bd70528_charger_set_property, 665 - .property_is_writeable = bd70528_prop_is_writable, 666 - }; 667 - 668 - static int bd70528_power_probe(struct platform_device *pdev) 669 - { 670 - struct bd70528_psy *bdpsy; 671 - struct power_supply_config cfg = {}; 672 - 673 - bdpsy = devm_kzalloc(&pdev->dev, sizeof(*bdpsy), GFP_KERNEL); 674 - if (!bdpsy) 675 - return -ENOMEM; 676 - 677 - bdpsy->regmap = dev_get_regmap(pdev->dev.parent, NULL); 678 - if (!bdpsy->regmap) { 679 - dev_err(&pdev->dev, "No regmap found for chip\n"); 680 - return -EINVAL; 681 - } 682 - bdpsy->dev = &pdev->dev; 683 - 684 - platform_set_drvdata(pdev, bdpsy); 685 - cfg.drv_data = bdpsy; 686 - cfg.of_node = pdev->dev.parent->of_node; 687 - 688 - bdpsy->psy = devm_power_supply_register(&pdev->dev, 689 - &bd70528_charger_desc, &cfg); 690 - if (IS_ERR(bdpsy->psy)) { 691 - dev_err(&pdev->dev, "failed: power supply register\n"); 692 - return PTR_ERR(bdpsy->psy); 693 - } 694 - 695 - return bd70528_get_irqs(pdev, bdpsy); 696 - } 697 - 698 - static struct platform_driver bd70528_power = { 699 - .driver = { 700 - .name = "bd70528-power" 701 - }, 702 - .probe = bd70528_power_probe, 703 - }; 704 - 705 - module_platform_driver(bd70528_power); 706 - 707 - MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>"); 708 - MODULE_DESCRIPTION("BD70528 power-supply driver"); 709 - MODULE_LICENSE("GPL"); 710 - MODULE_ALIAS("platform:bd70528-power");
+2 -9
drivers/power/supply/bq24190_charger.c
··· 5 5 * Author: Mark A. Greer <mgreer@animalcreek.com> 6 6 */ 7 7 8 + #include <linux/mod_devicetable.h> 8 9 #include <linux/module.h> 9 10 #include <linux/interrupt.h> 10 11 #include <linux/delay.h> 11 - #include <linux/of_irq.h> 12 - #include <linux/of_device.h> 13 12 #include <linux/pm_runtime.h> 14 13 #include <linux/power_supply.h> 15 14 #include <linux/power/bq24190_charger.h> ··· 1958 1959 }; 1959 1960 MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids); 1960 1961 1961 - #ifdef CONFIG_OF 1962 1962 static const struct of_device_id bq24190_of_match[] = { 1963 1963 { .compatible = "ti,bq24190", }, 1964 1964 { .compatible = "ti,bq24192", }, ··· 1966 1968 { }, 1967 1969 }; 1968 1970 MODULE_DEVICE_TABLE(of, bq24190_of_match); 1969 - #else 1970 - static const struct of_device_id bq24190_of_match[] = { 1971 - { }, 1972 - }; 1973 - #endif 1974 1971 1975 1972 static struct i2c_driver bq24190_driver = { 1976 1973 .probe = bq24190_probe, ··· 1974 1981 .driver = { 1975 1982 .name = "bq24190-charger", 1976 1983 .pm = &bq24190_pm_ops, 1977 - .of_match_table = of_match_ptr(bq24190_of_match), 1984 + .of_match_table = bq24190_of_match, 1978 1985 }, 1979 1986 }; 1980 1987 module_i2c_driver(bq24190_driver);
+1
drivers/power/supply/charger-manager.c
··· 1279 1279 }, 1280 1280 {}, 1281 1281 }; 1282 + MODULE_DEVICE_TABLE(of, charger_manager_match); 1282 1283 1283 1284 static struct charger_desc *of_cm_parse_desc(struct device *dev) 1284 1285 {
+16 -3
drivers/power/supply/cpcap-battery.c
··· 667 667 if (!empty->voltage) 668 668 return -ENODATA; 669 669 val->intval = empty->counter_uah - latest->counter_uah; 670 - if (val->intval < 0) 670 + if (val->intval < 0) { 671 + /* Assume invalid config if CHARGE_NOW is -20% */ 672 + if (ddata->charge_full && abs(val->intval) > ddata->charge_full/5) { 673 + empty->voltage = 0; 674 + ddata->charge_full = 0; 675 + return -ENODATA; 676 + } 671 677 val->intval = 0; 672 - else if (ddata->charge_full && ddata->charge_full < val->intval) 678 + } else if (ddata->charge_full && ddata->charge_full < val->intval) { 679 + /* Assume invalid config if CHARGE_NOW exceeds CHARGE_FULL by 20% */ 680 + if (val->intval > (6*ddata->charge_full)/5) { 681 + empty->voltage = 0; 682 + ddata->charge_full = 0; 683 + return -ENODATA; 684 + } 673 685 val->intval = ddata->charge_full; 686 + } 674 687 break; 675 688 case POWER_SUPPLY_PROP_CHARGE_FULL: 676 689 if (!ddata->charge_full) ··· 760 747 case POWER_SUPPLY_PROP_CHARGE_FULL: 761 748 if (val->intval < 0) 762 749 return -EINVAL; 763 - if (val->intval > ddata->config.info.charge_full_design) 750 + if (val->intval > (6*ddata->config.info.charge_full_design)/5) 764 751 return -EINVAL; 765 752 766 753 ddata->charge_full = val->intval;
+20 -19
drivers/power/supply/cpcap-charger.c
··· 173 173 POWER_SUPPLY_PROP_CURRENT_NOW, 174 174 }; 175 175 176 - /* No battery always shows temperature of -40000 */ 177 - static bool cpcap_charger_battery_found(struct cpcap_charger_ddata *ddata) 178 - { 179 - struct iio_channel *channel; 180 - int error, temperature; 181 - 182 - channel = ddata->channels[CPCAP_CHARGER_IIO_BATTDET]; 183 - error = iio_read_channel_processed(channel, &temperature); 184 - if (error < 0) { 185 - dev_warn(ddata->dev, "%s failed: %i\n", __func__, error); 186 - 187 - return false; 188 - } 189 - 190 - return temperature > -20000 && temperature < 60000; 191 - } 192 - 193 176 static int cpcap_charger_get_charge_voltage(struct cpcap_charger_ddata *ddata) 194 177 { 195 178 struct iio_channel *channel; ··· 683 700 684 701 if (!ddata->feeding_vbus && cpcap_charger_vbus_valid(ddata) && 685 702 s.chrgcurr1) { 686 - int max_current = 532000; 703 + int max_current; 687 704 int vchrg, ichrg; 705 + union power_supply_propval val; 706 + struct power_supply *battery; 688 707 689 - if (cpcap_charger_battery_found(ddata)) 708 + battery = power_supply_get_by_name("battery"); 709 + if (IS_ERR_OR_NULL(battery)) { 710 + dev_err(ddata->dev, "battery power_supply not available %li\n", 711 + PTR_ERR(battery)); 712 + return; 713 + } 714 + 715 + error = power_supply_get_property(battery, POWER_SUPPLY_PROP_PRESENT, &val); 716 + power_supply_put(battery); 717 + if (error) 718 + goto out_err; 719 + 720 + if (val.intval) { 690 721 max_current = 1596000; 722 + } else { 723 + dev_info(ddata->dev, "battery not inserted, charging disabled\n"); 724 + max_current = 0; 725 + } 691 726 692 727 if (max_current > ddata->limit_current) 693 728 max_current = ddata->limit_current;
+5 -37
drivers/power/supply/max17040_battery.c
··· 16 16 #include <linux/interrupt.h> 17 17 #include <linux/power_supply.h> 18 18 #include <linux/of_device.h> 19 - #include <linux/max17040_battery.h> 20 19 #include <linux/regmap.h> 21 20 #include <linux/slab.h> 22 21 ··· 141 142 struct regmap *regmap; 142 143 struct delayed_work work; 143 144 struct power_supply *battery; 144 - struct max17040_platform_data *pdata; 145 145 struct chip_data data; 146 146 147 147 /* battery capacity */ 148 148 int soc; 149 - /* State Of Charge */ 150 - int status; 151 149 /* Low alert threshold from 32% to 1% of the State of Charge */ 152 150 u32 low_soc_alert; 153 151 /* some devices return twice the capacity */ ··· 217 221 218 222 static int max17040_get_online(struct max17040_chip *chip) 219 223 { 220 - return chip->pdata && chip->pdata->battery_online ? 221 - chip->pdata->battery_online() : 1; 222 - } 223 - 224 - static int max17040_get_status(struct max17040_chip *chip) 225 - { 226 - if (!chip->pdata || !chip->pdata->charger_online 227 - || !chip->pdata->charger_enable) 228 - return POWER_SUPPLY_STATUS_UNKNOWN; 229 - 230 - if (max17040_get_soc(chip) > MAX17040_BATTERY_FULL) 231 - return POWER_SUPPLY_STATUS_FULL; 232 - 233 - if (chip->pdata->charger_online()) 234 - if (chip->pdata->charger_enable()) 235 - return POWER_SUPPLY_STATUS_CHARGING; 236 - else 237 - return POWER_SUPPLY_STATUS_NOT_CHARGING; 238 - else 239 - return POWER_SUPPLY_STATUS_DISCHARGING; 224 + return 1; 240 225 } 241 226 242 227 static int max17040_get_of_data(struct max17040_chip *chip) ··· 260 283 static void max17040_check_changes(struct max17040_chip *chip) 261 284 { 262 285 chip->soc = max17040_get_soc(chip); 263 - chip->status = max17040_get_status(chip); 264 286 } 265 287 266 288 static void max17040_queue_work(struct max17040_chip *chip) ··· 278 302 static void max17040_work(struct work_struct *work) 279 303 { 280 304 struct max17040_chip *chip; 281 - int last_soc, last_status; 305 + int last_soc; 282 306 283 307 chip = container_of(work, struct max17040_chip, work.work); 284 308 285 - /* store SOC and status to check changes */ 309 + /* store SOC to check changes */ 286 310 last_soc = chip->soc; 287 - last_status = chip->status; 288 311 max17040_check_changes(chip); 289 312 290 313 /* check changes and send uevent */ 291 - if (last_soc != chip->soc || last_status != chip->status) 314 + if (last_soc != chip->soc) 292 315 power_supply_changed(chip->battery); 293 316 294 317 max17040_queue_work(chip); ··· 336 361 static int max17040_enable_alert_irq(struct max17040_chip *chip) 337 362 { 338 363 struct i2c_client *client = chip->client; 339 - unsigned int flags; 340 364 int ret; 341 365 342 - flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; 343 366 ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, 344 - max17040_thread_handler, flags, 367 + max17040_thread_handler, IRQF_ONESHOT, 345 368 chip->battery->desc->name, chip); 346 369 347 370 return ret; ··· 388 415 struct max17040_chip *chip = power_supply_get_drvdata(psy); 389 416 390 417 switch (psp) { 391 - case POWER_SUPPLY_PROP_STATUS: 392 - val->intval = max17040_get_status(chip); 393 - break; 394 418 case POWER_SUPPLY_PROP_ONLINE: 395 419 val->intval = max17040_get_online(chip); 396 420 break; ··· 414 444 }; 415 445 416 446 static enum power_supply_property max17040_battery_props[] = { 417 - POWER_SUPPLY_PROP_STATUS, 418 447 POWER_SUPPLY_PROP_ONLINE, 419 448 POWER_SUPPLY_PROP_VOLTAGE_NOW, 420 449 POWER_SUPPLY_PROP_CAPACITY, ··· 449 480 450 481 chip->client = client; 451 482 chip->regmap = devm_regmap_init_i2c(client, &max17040_regmap); 452 - chip->pdata = client->dev.platform_data; 453 483 chip_id = (enum chip_id) id->driver_data; 454 484 if (client->dev.of_node) { 455 485 ret = max17040_get_of_data(chip);
+1 -1
drivers/power/supply/max17042_battery.c
··· 1104 1104 } 1105 1105 1106 1106 if (client->irq) { 1107 - unsigned int flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; 1107 + unsigned int flags = IRQF_ONESHOT; 1108 1108 1109 1109 /* 1110 1110 * On ACPI systems the IRQ may be handled by ACPI-event code,
-1249
drivers/power/supply/pm2301_charger.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - /* 3 - * Copyright 2012 ST Ericsson. 4 - * 5 - * Power supply driver for ST Ericsson pm2xxx_charger charger 6 - */ 7 - 8 - #include <linux/init.h> 9 - #include <linux/module.h> 10 - #include <linux/device.h> 11 - #include <linux/interrupt.h> 12 - #include <linux/delay.h> 13 - #include <linux/slab.h> 14 - #include <linux/platform_device.h> 15 - #include <linux/power_supply.h> 16 - #include <linux/regulator/consumer.h> 17 - #include <linux/err.h> 18 - #include <linux/i2c.h> 19 - #include <linux/workqueue.h> 20 - #include <linux/mfd/abx500/ab8500.h> 21 - #include <linux/pm2301_charger.h> 22 - #include <linux/gpio.h> 23 - #include <linux/pm_runtime.h> 24 - #include <linux/pm.h> 25 - 26 - #include "ab8500-bm.h" 27 - #include "ab8500-chargalg.h" 28 - #include "pm2301_charger.h" 29 - 30 - #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \ 31 - struct pm2xxx_charger, ac_chg) 32 - #define SLEEP_MIN 50 33 - #define SLEEP_MAX 100 34 - #define PM2XXX_AUTOSUSPEND_DELAY 500 35 - 36 - static int pm2xxx_interrupt_registers[] = { 37 - PM2XXX_REG_INT1, 38 - PM2XXX_REG_INT2, 39 - PM2XXX_REG_INT3, 40 - PM2XXX_REG_INT4, 41 - PM2XXX_REG_INT5, 42 - PM2XXX_REG_INT6, 43 - }; 44 - 45 - static enum power_supply_property pm2xxx_charger_ac_props[] = { 46 - POWER_SUPPLY_PROP_HEALTH, 47 - POWER_SUPPLY_PROP_PRESENT, 48 - POWER_SUPPLY_PROP_ONLINE, 49 - POWER_SUPPLY_PROP_VOLTAGE_AVG, 50 - }; 51 - 52 - static int pm2xxx_charger_voltage_map[] = { 53 - 3500, 54 - 3525, 55 - 3550, 56 - 3575, 57 - 3600, 58 - 3625, 59 - 3650, 60 - 3675, 61 - 3700, 62 - 3725, 63 - 3750, 64 - 3775, 65 - 3800, 66 - 3825, 67 - 3850, 68 - 3875, 69 - 3900, 70 - 3925, 71 - 3950, 72 - 3975, 73 - 4000, 74 - 4025, 75 - 4050, 76 - 4075, 77 - 4100, 78 - 4125, 79 - 4150, 80 - 4175, 81 - 4200, 82 - 4225, 83 - 4250, 84 - 4275, 85 - 4300, 86 - }; 87 - 88 - static int pm2xxx_charger_current_map[] = { 89 - 200, 90 - 200, 91 - 400, 92 - 600, 93 - 800, 94 - 1000, 95 - 1200, 96 - 1400, 97 - 1600, 98 - 1800, 99 - 2000, 100 - 2200, 101 - 2400, 102 - 2600, 103 - 2800, 104 - 3000, 105 - }; 106 - 107 - static void set_lpn_pin(struct pm2xxx_charger *pm2) 108 - { 109 - if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) { 110 - gpio_set_value(pm2->lpn_pin, 1); 111 - usleep_range(SLEEP_MIN, SLEEP_MAX); 112 - } 113 - } 114 - 115 - static void clear_lpn_pin(struct pm2xxx_charger *pm2) 116 - { 117 - if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) 118 - gpio_set_value(pm2->lpn_pin, 0); 119 - } 120 - 121 - static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) 122 - { 123 - int ret; 124 - 125 - /* wake up the device */ 126 - pm_runtime_get_sync(pm2->dev); 127 - 128 - ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 129 - 1, val); 130 - if (ret < 0) 131 - dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); 132 - else 133 - ret = 0; 134 - 135 - pm_runtime_put_sync(pm2->dev); 136 - 137 - return ret; 138 - } 139 - 140 - static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) 141 - { 142 - int ret; 143 - 144 - /* wake up the device */ 145 - pm_runtime_get_sync(pm2->dev); 146 - 147 - ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, 148 - 1, &val); 149 - if (ret < 0) 150 - dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); 151 - else 152 - ret = 0; 153 - 154 - pm_runtime_put_sync(pm2->dev); 155 - 156 - return ret; 157 - } 158 - 159 - static int pm2xxx_charging_enable_mngt(struct pm2xxx_charger *pm2) 160 - { 161 - int ret; 162 - 163 - /* Enable charging */ 164 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2, 165 - (PM2XXX_CH_AUTO_RESUME_EN | PM2XXX_CHARGER_ENA)); 166 - 167 - return ret; 168 - } 169 - 170 - static int pm2xxx_charging_disable_mngt(struct pm2xxx_charger *pm2) 171 - { 172 - int ret; 173 - 174 - /* Disable SW EOC ctrl */ 175 - ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, PM2XXX_SWCTRL_HW); 176 - if (ret < 0) { 177 - dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); 178 - return ret; 179 - } 180 - 181 - /* Disable charging */ 182 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2, 183 - (PM2XXX_CH_AUTO_RESUME_DIS | PM2XXX_CHARGER_DIS)); 184 - if (ret < 0) { 185 - dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); 186 - return ret; 187 - } 188 - 189 - return 0; 190 - } 191 - 192 - static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val) 193 - { 194 - queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work); 195 - 196 - return 0; 197 - } 198 - 199 - 200 - static int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val) 201 - { 202 - queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work); 203 - 204 - return 0; 205 - } 206 - 207 - static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val) 208 - { 209 - dev_err(pm2->dev, "Overvoltage detected\n"); 210 - pm2->flags.ovv = true; 211 - power_supply_changed(pm2->ac_chg.psy); 212 - 213 - /* Schedule a new HW failure check */ 214 - queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0); 215 - 216 - return 0; 217 - } 218 - 219 - static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) 220 - { 221 - dev_dbg(pm2->dev , "20 minutes watchdog expired\n"); 222 - 223 - pm2->ac.wd_expired = true; 224 - power_supply_changed(pm2->ac_chg.psy); 225 - 226 - return 0; 227 - } 228 - 229 - static int pm2xxx_charger_vbat_lsig_mngt(struct pm2xxx_charger *pm2, int val) 230 - { 231 - int ret; 232 - 233 - switch (val) { 234 - case PM2XXX_INT1_ITVBATLOWR: 235 - dev_dbg(pm2->dev, "VBAT grows above VBAT_LOW level\n"); 236 - /* Enable SW EOC ctrl */ 237 - ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, 238 - PM2XXX_SWCTRL_SW); 239 - if (ret < 0) { 240 - dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); 241 - return ret; 242 - } 243 - break; 244 - 245 - case PM2XXX_INT1_ITVBATLOWF: 246 - dev_dbg(pm2->dev, "VBAT drops below VBAT_LOW level\n"); 247 - /* Disable SW EOC ctrl */ 248 - ret = pm2xxx_reg_write(pm2, PM2XXX_SW_CTRL_REG, 249 - PM2XXX_SWCTRL_HW); 250 - if (ret < 0) { 251 - dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); 252 - return ret; 253 - } 254 - break; 255 - 256 - default: 257 - dev_err(pm2->dev, "Unknown VBAT level\n"); 258 - } 259 - 260 - return 0; 261 - } 262 - 263 - static int pm2xxx_charger_bat_disc_mngt(struct pm2xxx_charger *pm2, int val) 264 - { 265 - dev_dbg(pm2->dev, "battery disconnected\n"); 266 - 267 - return 0; 268 - } 269 - 270 - static int pm2xxx_charger_detection(struct pm2xxx_charger *pm2, u8 *val) 271 - { 272 - int ret; 273 - 274 - ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT2, val); 275 - 276 - if (ret < 0) { 277 - dev_err(pm2->dev, "Charger detection failed\n"); 278 - goto out; 279 - } 280 - 281 - *val &= (PM2XXX_INT2_S_ITVPWR1PLUG | PM2XXX_INT2_S_ITVPWR2PLUG); 282 - 283 - out: 284 - return ret; 285 - } 286 - 287 - static int pm2xxx_charger_itv_pwr_plug_mngt(struct pm2xxx_charger *pm2, int val) 288 - { 289 - 290 - int ret; 291 - u8 read_val; 292 - 293 - /* 294 - * Since we can't be sure that the events are received 295 - * synchronously, we have the check if the main charger is 296 - * connected by reading the interrupt source register. 297 - */ 298 - ret = pm2xxx_charger_detection(pm2, &read_val); 299 - 300 - if ((ret == 0) && read_val) { 301 - pm2->ac.charger_connected = 1; 302 - pm2->ac_conn = true; 303 - queue_work(pm2->charger_wq, &pm2->ac_work); 304 - } 305 - 306 - 307 - return ret; 308 - } 309 - 310 - static int pm2xxx_charger_itv_pwr_unplug_mngt(struct pm2xxx_charger *pm2, 311 - int val) 312 - { 313 - pm2->ac.charger_connected = 0; 314 - queue_work(pm2->charger_wq, &pm2->ac_work); 315 - 316 - return 0; 317 - } 318 - 319 - static int pm2_int_reg0(void *pm2_data, int val) 320 - { 321 - struct pm2xxx_charger *pm2 = pm2_data; 322 - int ret = 0; 323 - 324 - if (val & PM2XXX_INT1_ITVBATLOWR) { 325 - ret = pm2xxx_charger_vbat_lsig_mngt(pm2, 326 - PM2XXX_INT1_ITVBATLOWR); 327 - if (ret < 0) 328 - goto out; 329 - } 330 - 331 - if (val & PM2XXX_INT1_ITVBATLOWF) { 332 - ret = pm2xxx_charger_vbat_lsig_mngt(pm2, 333 - PM2XXX_INT1_ITVBATLOWF); 334 - if (ret < 0) 335 - goto out; 336 - } 337 - 338 - if (val & PM2XXX_INT1_ITVBATDISCONNECT) { 339 - ret = pm2xxx_charger_bat_disc_mngt(pm2, 340 - PM2XXX_INT1_ITVBATDISCONNECT); 341 - if (ret < 0) 342 - goto out; 343 - } 344 - out: 345 - return ret; 346 - } 347 - 348 - static int pm2_int_reg1(void *pm2_data, int val) 349 - { 350 - struct pm2xxx_charger *pm2 = pm2_data; 351 - int ret = 0; 352 - 353 - if (val & (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)) { 354 - dev_dbg(pm2->dev , "Main charger plugged\n"); 355 - ret = pm2xxx_charger_itv_pwr_plug_mngt(pm2, val & 356 - (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)); 357 - } 358 - 359 - if (val & 360 - (PM2XXX_INT2_ITVPWR1UNPLUG | PM2XXX_INT2_ITVPWR2UNPLUG)) { 361 - dev_dbg(pm2->dev , "Main charger unplugged\n"); 362 - ret = pm2xxx_charger_itv_pwr_unplug_mngt(pm2, val & 363 - (PM2XXX_INT2_ITVPWR1UNPLUG | 364 - PM2XXX_INT2_ITVPWR2UNPLUG)); 365 - } 366 - 367 - return ret; 368 - } 369 - 370 - static int pm2_int_reg2(void *pm2_data, int val) 371 - { 372 - struct pm2xxx_charger *pm2 = pm2_data; 373 - int ret = 0; 374 - 375 - if (val & PM2XXX_INT3_ITAUTOTIMEOUTWD) 376 - ret = pm2xxx_charger_wd_exp_mngt(pm2, val); 377 - 378 - if (val & (PM2XXX_INT3_ITCHPRECHARGEWD | 379 - PM2XXX_INT3_ITCHCCWD | PM2XXX_INT3_ITCHCVWD)) { 380 - dev_dbg(pm2->dev, 381 - "Watchdog occurred for precharge, CC and CV charge\n"); 382 - } 383 - 384 - return ret; 385 - } 386 - 387 - static int pm2_int_reg3(void *pm2_data, int val) 388 - { 389 - struct pm2xxx_charger *pm2 = pm2_data; 390 - int ret = 0; 391 - 392 - if (val & (PM2XXX_INT4_ITCHARGINGON)) { 393 - dev_dbg(pm2->dev , 394 - "charging operation has started\n"); 395 - } 396 - 397 - if (val & (PM2XXX_INT4_ITVRESUME)) { 398 - dev_dbg(pm2->dev, 399 - "battery discharged down to VResume threshold\n"); 400 - } 401 - 402 - if (val & (PM2XXX_INT4_ITBATTFULL)) { 403 - dev_dbg(pm2->dev , "battery fully detected\n"); 404 - } 405 - 406 - if (val & (PM2XXX_INT4_ITCVPHASE)) { 407 - dev_dbg(pm2->dev, "CV phase enter with 0.5C charging\n"); 408 - } 409 - 410 - if (val & (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)) { 411 - pm2->failure_case = VPWR_OVV; 412 - ret = pm2xxx_charger_ovv_mngt(pm2, val & 413 - (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)); 414 - dev_dbg(pm2->dev, "VPWR/VSYSTEM overvoltage detected\n"); 415 - } 416 - 417 - if (val & (PM2XXX_INT4_S_ITBATTEMPCOLD | 418 - PM2XXX_INT4_S_ITBATTEMPHOT)) { 419 - ret = pm2xxx_charger_batt_therm_mngt(pm2, val & 420 - (PM2XXX_INT4_S_ITBATTEMPCOLD | 421 - PM2XXX_INT4_S_ITBATTEMPHOT)); 422 - dev_dbg(pm2->dev, "BTEMP is too Low/High\n"); 423 - } 424 - 425 - return ret; 426 - } 427 - 428 - static int pm2_int_reg4(void *pm2_data, int val) 429 - { 430 - struct pm2xxx_charger *pm2 = pm2_data; 431 - int ret = 0; 432 - 433 - if (val & PM2XXX_INT5_ITVSYSTEMOVV) { 434 - pm2->failure_case = VSYSTEM_OVV; 435 - ret = pm2xxx_charger_ovv_mngt(pm2, val & 436 - PM2XXX_INT5_ITVSYSTEMOVV); 437 - dev_dbg(pm2->dev, "VSYSTEM overvoltage detected\n"); 438 - } 439 - 440 - if (val & (PM2XXX_INT5_ITTHERMALWARNINGFALL | 441 - PM2XXX_INT5_ITTHERMALWARNINGRISE | 442 - PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | 443 - PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)) { 444 - dev_dbg(pm2->dev, "BTEMP die temperature is too Low/High\n"); 445 - ret = pm2xxx_charger_die_therm_mngt(pm2, val & 446 - (PM2XXX_INT5_ITTHERMALWARNINGFALL | 447 - PM2XXX_INT5_ITTHERMALWARNINGRISE | 448 - PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | 449 - PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)); 450 - } 451 - 452 - return ret; 453 - } 454 - 455 - static int pm2_int_reg5(void *pm2_data, int val) 456 - { 457 - struct pm2xxx_charger *pm2 = pm2_data; 458 - 459 - if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { 460 - dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); 461 - } 462 - 463 - if (val & (PM2XXX_INT6_ITVPWR2VALIDRISE | 464 - PM2XXX_INT6_ITVPWR1VALIDRISE | 465 - PM2XXX_INT6_ITVPWR2VALIDFALL | 466 - PM2XXX_INT6_ITVPWR1VALIDFALL)) { 467 - dev_dbg(pm2->dev, "Falling/Rising edge on WPWR1/2\n"); 468 - } 469 - 470 - return 0; 471 - } 472 - 473 - static irqreturn_t pm2xxx_irq_int(int irq, void *data) 474 - { 475 - struct pm2xxx_charger *pm2 = data; 476 - struct pm2xxx_interrupts *interrupt = pm2->pm2_int; 477 - int i; 478 - 479 - /* wake up the device */ 480 - pm_runtime_get_sync(pm2->dev); 481 - 482 - do { 483 - for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { 484 - pm2xxx_reg_read(pm2, 485 - pm2xxx_interrupt_registers[i], 486 - &(interrupt->reg[i])); 487 - 488 - if (interrupt->reg[i] > 0) 489 - interrupt->handler[i](pm2, interrupt->reg[i]); 490 - } 491 - } while (gpio_get_value(pm2->pdata->gpio_irq_number) == 0); 492 - 493 - pm_runtime_mark_last_busy(pm2->dev); 494 - pm_runtime_put_autosuspend(pm2->dev); 495 - 496 - return IRQ_HANDLED; 497 - } 498 - 499 - static int pm2xxx_charger_get_ac_cv(struct pm2xxx_charger *pm2) 500 - { 501 - int ret = 0; 502 - u8 val; 503 - 504 - if (pm2->ac.charger_connected && pm2->ac.charger_online) { 505 - 506 - ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &val); 507 - if (ret < 0) { 508 - dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); 509 - goto out; 510 - } 511 - 512 - if (val & PM2XXX_INT4_S_ITCVPHASE) 513 - ret = PM2XXX_CONST_VOLT; 514 - else 515 - ret = PM2XXX_CONST_CURR; 516 - } 517 - out: 518 - return ret; 519 - } 520 - 521 - static int pm2xxx_current_to_regval(int curr) 522 - { 523 - int i; 524 - 525 - if (curr < pm2xxx_charger_current_map[0]) 526 - return 0; 527 - 528 - for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_current_map); i++) { 529 - if (curr < pm2xxx_charger_current_map[i]) 530 - return (i - 1); 531 - } 532 - 533 - i = ARRAY_SIZE(pm2xxx_charger_current_map) - 1; 534 - if (curr == pm2xxx_charger_current_map[i]) 535 - return i; 536 - else 537 - return -EINVAL; 538 - } 539 - 540 - static int pm2xxx_voltage_to_regval(int curr) 541 - { 542 - int i; 543 - 544 - if (curr < pm2xxx_charger_voltage_map[0]) 545 - return 0; 546 - 547 - for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_voltage_map); i++) { 548 - if (curr < pm2xxx_charger_voltage_map[i]) 549 - return i - 1; 550 - } 551 - 552 - i = ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1; 553 - if (curr == pm2xxx_charger_voltage_map[i]) 554 - return i; 555 - else 556 - return -EINVAL; 557 - } 558 - 559 - static int pm2xxx_charger_update_charger_current(struct ux500_charger *charger, 560 - int ich_out) 561 - { 562 - int ret; 563 - int curr_index; 564 - struct pm2xxx_charger *pm2; 565 - u8 val; 566 - 567 - if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS) 568 - pm2 = to_pm2xxx_charger_ac_device_info(charger); 569 - else 570 - return -ENXIO; 571 - 572 - curr_index = pm2xxx_current_to_regval(ich_out); 573 - if (curr_index < 0) { 574 - dev_err(pm2->dev, 575 - "Charger current too high, charging not started\n"); 576 - return -ENXIO; 577 - } 578 - 579 - ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val); 580 - if (ret >= 0) { 581 - val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK; 582 - val |= curr_index; 583 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val); 584 - if (ret < 0) { 585 - dev_err(pm2->dev, 586 - "%s write failed\n", __func__); 587 - } 588 - } 589 - else 590 - dev_err(pm2->dev, "%s read failed\n", __func__); 591 - 592 - return ret; 593 - } 594 - 595 - static int pm2xxx_charger_ac_get_property(struct power_supply *psy, 596 - enum power_supply_property psp, 597 - union power_supply_propval *val) 598 - { 599 - struct pm2xxx_charger *pm2; 600 - 601 - pm2 = to_pm2xxx_charger_ac_device_info(psy_to_ux500_charger(psy)); 602 - 603 - switch (psp) { 604 - case POWER_SUPPLY_PROP_HEALTH: 605 - if (pm2->flags.mainextchnotok) 606 - val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; 607 - else if (pm2->ac.wd_expired) 608 - val->intval = POWER_SUPPLY_HEALTH_DEAD; 609 - else if (pm2->flags.main_thermal_prot) 610 - val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 611 - else if (pm2->flags.ovv) 612 - val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 613 - else 614 - val->intval = POWER_SUPPLY_HEALTH_GOOD; 615 - break; 616 - case POWER_SUPPLY_PROP_ONLINE: 617 - val->intval = pm2->ac.charger_online; 618 - break; 619 - case POWER_SUPPLY_PROP_PRESENT: 620 - val->intval = pm2->ac.charger_connected; 621 - break; 622 - case POWER_SUPPLY_PROP_VOLTAGE_AVG: 623 - pm2->ac.cv_active = pm2xxx_charger_get_ac_cv(pm2); 624 - val->intval = pm2->ac.cv_active; 625 - break; 626 - default: 627 - return -EINVAL; 628 - } 629 - return 0; 630 - } 631 - 632 - static int pm2xxx_charging_init(struct pm2xxx_charger *pm2) 633 - { 634 - int ret = 0; 635 - 636 - /* enable CC and CV watchdog */ 637 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG3, 638 - (PM2XXX_CH_WD_CV_PHASE_60MIN | PM2XXX_CH_WD_CC_PHASE_60MIN)); 639 - if( ret < 0) 640 - return ret; 641 - 642 - /* enable precharge watchdog */ 643 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG4, 644 - PM2XXX_CH_WD_PRECH_PHASE_60MIN); 645 - 646 - /* Disable auto timeout */ 647 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG5, 648 - PM2XXX_CH_WD_AUTO_TIMEOUT_20MIN); 649 - 650 - /* 651 - * EOC current level = 100mA 652 - * Precharge current level = 100mA 653 - * CC current level = 1000mA 654 - */ 655 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, 656 - (PM2XXX_DIR_CH_CC_CURRENT_1000MA | 657 - PM2XXX_CH_PRECH_CURRENT_100MA | 658 - PM2XXX_CH_EOC_CURRENT_100MA)); 659 - 660 - /* 661 - * recharge threshold = 3.8V 662 - * Precharge to CC threshold = 2.9V 663 - */ 664 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG7, 665 - (PM2XXX_CH_PRECH_VOL_2_9 | PM2XXX_CH_VRESUME_VOL_3_8)); 666 - 667 - /* float voltage charger level = 4.2V */ 668 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, 669 - PM2XXX_CH_VOLT_4_2); 670 - 671 - /* Voltage drop between VBAT and VSYS in HW charging = 300mV */ 672 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG9, 673 - (PM2XXX_CH_150MV_DROP_300MV | PM2XXX_CHARCHING_INFO_DIS | 674 - PM2XXX_CH_CC_REDUCED_CURRENT_IDENT | 675 - PM2XXX_CH_CC_MODEDROP_DIS)); 676 - 677 - /* Input charger level of over voltage = 10V */ 678 - ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR2, 679 - PM2XXX_VPWR2_OVV_10); 680 - ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR1, 681 - PM2XXX_VPWR1_OVV_10); 682 - 683 - /* Input charger drop */ 684 - ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR2, 685 - (PM2XXX_VPWR2_HW_OPT_DIS | PM2XXX_VPWR2_VALID_DIS | 686 - PM2XXX_VPWR2_DROP_DIS)); 687 - ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR1, 688 - (PM2XXX_VPWR1_HW_OPT_DIS | PM2XXX_VPWR1_VALID_DIS | 689 - PM2XXX_VPWR1_DROP_DIS)); 690 - 691 - /* Disable battery low monitoring */ 692 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG, 693 - PM2XXX_VBAT_LOW_MONITORING_ENA); 694 - 695 - return ret; 696 - } 697 - 698 - static int pm2xxx_charger_ac_en(struct ux500_charger *charger, 699 - int enable, int vset, int iset) 700 - { 701 - int ret; 702 - int volt_index; 703 - int curr_index; 704 - u8 val; 705 - 706 - struct pm2xxx_charger *pm2 = to_pm2xxx_charger_ac_device_info(charger); 707 - 708 - if (enable) { 709 - if (!pm2->ac.charger_connected) { 710 - dev_dbg(pm2->dev, "AC charger not connected\n"); 711 - return -ENXIO; 712 - } 713 - 714 - dev_dbg(pm2->dev, "Enable AC: %dmV %dmA\n", vset, iset); 715 - if (!pm2->vddadc_en_ac) { 716 - ret = regulator_enable(pm2->regu); 717 - if (ret) 718 - dev_warn(pm2->dev, 719 - "Failed to enable vddadc regulator\n"); 720 - else 721 - pm2->vddadc_en_ac = true; 722 - } 723 - 724 - ret = pm2xxx_charging_init(pm2); 725 - if (ret < 0) { 726 - dev_err(pm2->dev, "%s charging init failed\n", 727 - __func__); 728 - goto error_occured; 729 - } 730 - 731 - volt_index = pm2xxx_voltage_to_regval(vset); 732 - curr_index = pm2xxx_current_to_regval(iset); 733 - 734 - if (volt_index < 0 || curr_index < 0) { 735 - dev_err(pm2->dev, 736 - "Charger voltage or current too high, " 737 - "charging not started\n"); 738 - return -ENXIO; 739 - } 740 - 741 - ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG8, &val); 742 - if (ret < 0) { 743 - dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); 744 - goto error_occured; 745 - } 746 - val &= ~PM2XXX_CH_VOLT_MASK; 747 - val |= volt_index; 748 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, val); 749 - if (ret < 0) { 750 - dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); 751 - goto error_occured; 752 - } 753 - 754 - ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val); 755 - if (ret < 0) { 756 - dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); 757 - goto error_occured; 758 - } 759 - val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK; 760 - val |= curr_index; 761 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val); 762 - if (ret < 0) { 763 - dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); 764 - goto error_occured; 765 - } 766 - 767 - if (!pm2->bat->enable_overshoot) { 768 - ret = pm2xxx_reg_read(pm2, PM2XXX_LED_CTRL_REG, &val); 769 - if (ret < 0) { 770 - dev_err(pm2->dev, "%s pm2xxx read failed\n", 771 - __func__); 772 - goto error_occured; 773 - } 774 - val |= PM2XXX_ANTI_OVERSHOOT_EN; 775 - ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, val); 776 - if (ret < 0) { 777 - dev_err(pm2->dev, "%s pm2xxx write failed\n", 778 - __func__); 779 - goto error_occured; 780 - } 781 - } 782 - 783 - ret = pm2xxx_charging_enable_mngt(pm2); 784 - if (ret < 0) { 785 - dev_err(pm2->dev, "Failed to enable" 786 - "pm2xxx ac charger\n"); 787 - goto error_occured; 788 - } 789 - 790 - pm2->ac.charger_online = 1; 791 - } else { 792 - pm2->ac.charger_online = 0; 793 - pm2->ac.wd_expired = false; 794 - 795 - /* Disable regulator if enabled */ 796 - if (pm2->vddadc_en_ac) { 797 - regulator_disable(pm2->regu); 798 - pm2->vddadc_en_ac = false; 799 - } 800 - 801 - ret = pm2xxx_charging_disable_mngt(pm2); 802 - if (ret < 0) { 803 - dev_err(pm2->dev, "failed to disable" 804 - "pm2xxx ac charger\n"); 805 - goto error_occured; 806 - } 807 - 808 - dev_dbg(pm2->dev, "PM2301: " "Disabled AC charging\n"); 809 - } 810 - power_supply_changed(pm2->ac_chg.psy); 811 - 812 - error_occured: 813 - return ret; 814 - } 815 - 816 - static int pm2xxx_charger_watchdog_kick(struct ux500_charger *charger) 817 - { 818 - int ret; 819 - struct pm2xxx_charger *pm2; 820 - 821 - if (charger->psy->desc->type == POWER_SUPPLY_TYPE_MAINS) 822 - pm2 = to_pm2xxx_charger_ac_device_info(charger); 823 - else 824 - return -ENXIO; 825 - 826 - ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_WD_KICK, WD_TIMER); 827 - if (ret) 828 - dev_err(pm2->dev, "Failed to kick WD!\n"); 829 - 830 - return ret; 831 - } 832 - 833 - static void pm2xxx_charger_ac_work(struct work_struct *work) 834 - { 835 - struct pm2xxx_charger *pm2 = container_of(work, 836 - struct pm2xxx_charger, ac_work); 837 - 838 - 839 - power_supply_changed(pm2->ac_chg.psy); 840 - sysfs_notify(&pm2->ac_chg.psy->dev.kobj, NULL, "present"); 841 - }; 842 - 843 - static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work) 844 - { 845 - u8 reg_value; 846 - 847 - struct pm2xxx_charger *pm2 = container_of(work, 848 - struct pm2xxx_charger, check_hw_failure_work.work); 849 - 850 - if (pm2->flags.ovv) { 851 - pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &reg_value); 852 - 853 - if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV | 854 - PM2XXX_INT4_S_ITVPWR2OVV))) { 855 - pm2->flags.ovv = false; 856 - power_supply_changed(pm2->ac_chg.psy); 857 - } 858 - } 859 - 860 - /* If we still have a failure, schedule a new check */ 861 - if (pm2->flags.ovv) { 862 - queue_delayed_work(pm2->charger_wq, 863 - &pm2->check_hw_failure_work, round_jiffies(HZ)); 864 - } 865 - } 866 - 867 - static void pm2xxx_charger_check_main_thermal_prot_work( 868 - struct work_struct *work) 869 - { 870 - int ret; 871 - u8 val; 872 - 873 - struct pm2xxx_charger *pm2 = container_of(work, struct pm2xxx_charger, 874 - check_main_thermal_prot_work); 875 - 876 - /* Check if die temp warning is still active */ 877 - ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT5, &val); 878 - if (ret < 0) { 879 - dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); 880 - return; 881 - } 882 - if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGRISE 883 - | PM2XXX_INT5_S_ITTHERMALSHUTDOWNRISE)) 884 - pm2->flags.main_thermal_prot = true; 885 - else if (val & (PM2XXX_INT5_S_ITTHERMALWARNINGFALL 886 - | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL)) 887 - pm2->flags.main_thermal_prot = false; 888 - 889 - power_supply_changed(pm2->ac_chg.psy); 890 - } 891 - 892 - static struct pm2xxx_interrupts pm2xxx_int = { 893 - .handler[0] = pm2_int_reg0, 894 - .handler[1] = pm2_int_reg1, 895 - .handler[2] = pm2_int_reg2, 896 - .handler[3] = pm2_int_reg3, 897 - .handler[4] = pm2_int_reg4, 898 - .handler[5] = pm2_int_reg5, 899 - }; 900 - 901 - static struct pm2xxx_irq pm2xxx_charger_irq[] = { 902 - {"PM2XXX_IRQ_INT", pm2xxx_irq_int}, 903 - }; 904 - 905 - static int __maybe_unused pm2xxx_wall_charger_resume(struct device *dev) 906 - { 907 - struct i2c_client *i2c_client = to_i2c_client(dev); 908 - struct pm2xxx_charger *pm2; 909 - 910 - pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); 911 - set_lpn_pin(pm2); 912 - 913 - /* If we still have a HW failure, schedule a new check */ 914 - if (pm2->flags.ovv) 915 - queue_delayed_work(pm2->charger_wq, 916 - &pm2->check_hw_failure_work, 0); 917 - 918 - return 0; 919 - } 920 - 921 - static int __maybe_unused pm2xxx_wall_charger_suspend(struct device *dev) 922 - { 923 - struct i2c_client *i2c_client = to_i2c_client(dev); 924 - struct pm2xxx_charger *pm2; 925 - 926 - pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); 927 - clear_lpn_pin(pm2); 928 - 929 - /* Cancel any pending HW failure check */ 930 - if (delayed_work_pending(&pm2->check_hw_failure_work)) 931 - cancel_delayed_work(&pm2->check_hw_failure_work); 932 - 933 - flush_work(&pm2->ac_work); 934 - flush_work(&pm2->check_main_thermal_prot_work); 935 - 936 - return 0; 937 - } 938 - 939 - static int __maybe_unused pm2xxx_runtime_suspend(struct device *dev) 940 - { 941 - struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); 942 - struct pm2xxx_charger *pm2; 943 - 944 - pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); 945 - clear_lpn_pin(pm2); 946 - 947 - return 0; 948 - } 949 - 950 - static int __maybe_unused pm2xxx_runtime_resume(struct device *dev) 951 - { 952 - struct i2c_client *pm2xxx_i2c_client = to_i2c_client(dev); 953 - struct pm2xxx_charger *pm2; 954 - 955 - pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(pm2xxx_i2c_client); 956 - 957 - if (gpio_is_valid(pm2->lpn_pin) && gpio_get_value(pm2->lpn_pin) == 0) 958 - set_lpn_pin(pm2); 959 - 960 - return 0; 961 - } 962 - 963 - static const struct dev_pm_ops pm2xxx_pm_ops __maybe_unused = { 964 - SET_SYSTEM_SLEEP_PM_OPS(pm2xxx_wall_charger_suspend, 965 - pm2xxx_wall_charger_resume) 966 - SET_RUNTIME_PM_OPS(pm2xxx_runtime_suspend, pm2xxx_runtime_resume, NULL) 967 - }; 968 - 969 - static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, 970 - const struct i2c_device_id *id) 971 - { 972 - struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data; 973 - struct power_supply_config psy_cfg = {}; 974 - struct pm2xxx_charger *pm2; 975 - int ret = 0; 976 - u8 val; 977 - int i; 978 - 979 - if (!pl_data) { 980 - dev_err(&i2c_client->dev, "No platform data supplied\n"); 981 - return -EINVAL; 982 - } 983 - 984 - pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); 985 - if (!pm2) { 986 - dev_err(&i2c_client->dev, "pm2xxx_charger allocation failed\n"); 987 - return -ENOMEM; 988 - } 989 - 990 - /* get parent data */ 991 - pm2->dev = &i2c_client->dev; 992 - 993 - pm2->pm2_int = &pm2xxx_int; 994 - 995 - /* get charger spcific platform data */ 996 - if (!pl_data->wall_charger) { 997 - dev_err(pm2->dev, "no charger platform data supplied\n"); 998 - ret = -EINVAL; 999 - goto free_device_info; 1000 - } 1001 - 1002 - pm2->pdata = pl_data->wall_charger; 1003 - 1004 - /* get battery specific platform data */ 1005 - if (!pl_data->battery) { 1006 - dev_err(pm2->dev, "no battery platform data supplied\n"); 1007 - ret = -EINVAL; 1008 - goto free_device_info; 1009 - } 1010 - 1011 - pm2->bat = pl_data->battery; 1012 - 1013 - if (!i2c_check_functionality(i2c_client->adapter, 1014 - I2C_FUNC_SMBUS_BYTE_DATA | 1015 - I2C_FUNC_SMBUS_READ_WORD_DATA)) { 1016 - ret = -ENODEV; 1017 - dev_info(pm2->dev, "pm2301 i2c_check_functionality failed\n"); 1018 - goto free_device_info; 1019 - } 1020 - 1021 - pm2->config.pm2xxx_i2c = i2c_client; 1022 - pm2->config.pm2xxx_id = (struct i2c_device_id *) id; 1023 - i2c_set_clientdata(i2c_client, pm2); 1024 - 1025 - /* AC supply */ 1026 - /* power_supply base class */ 1027 - pm2->ac_chg_desc.name = pm2->pdata->label; 1028 - pm2->ac_chg_desc.type = POWER_SUPPLY_TYPE_MAINS; 1029 - pm2->ac_chg_desc.properties = pm2xxx_charger_ac_props; 1030 - pm2->ac_chg_desc.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props); 1031 - pm2->ac_chg_desc.get_property = pm2xxx_charger_ac_get_property; 1032 - 1033 - psy_cfg.supplied_to = pm2->pdata->supplied_to; 1034 - psy_cfg.num_supplicants = pm2->pdata->num_supplicants; 1035 - /* pm2xxx_charger sub-class */ 1036 - pm2->ac_chg.ops.enable = &pm2xxx_charger_ac_en; 1037 - pm2->ac_chg.ops.kick_wd = &pm2xxx_charger_watchdog_kick; 1038 - pm2->ac_chg.ops.update_curr = &pm2xxx_charger_update_charger_current; 1039 - pm2->ac_chg.max_out_volt = pm2xxx_charger_voltage_map[ 1040 - ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1]; 1041 - pm2->ac_chg.max_out_curr = pm2xxx_charger_current_map[ 1042 - ARRAY_SIZE(pm2xxx_charger_current_map) - 1]; 1043 - pm2->ac_chg.wdt_refresh = WD_KICK_INTERVAL; 1044 - pm2->ac_chg.enabled = true; 1045 - pm2->ac_chg.external = true; 1046 - 1047 - /* Create a work queue for the charger */ 1048 - pm2->charger_wq = alloc_ordered_workqueue("pm2xxx_charger_wq", 1049 - WQ_MEM_RECLAIM); 1050 - if (pm2->charger_wq == NULL) { 1051 - ret = -ENOMEM; 1052 - dev_err(pm2->dev, "failed to create work queue\n"); 1053 - goto free_device_info; 1054 - } 1055 - 1056 - /* Init work for charger detection */ 1057 - INIT_WORK(&pm2->ac_work, pm2xxx_charger_ac_work); 1058 - 1059 - /* Init work for checking HW status */ 1060 - INIT_WORK(&pm2->check_main_thermal_prot_work, 1061 - pm2xxx_charger_check_main_thermal_prot_work); 1062 - 1063 - /* Init work for HW failure check */ 1064 - INIT_DEFERRABLE_WORK(&pm2->check_hw_failure_work, 1065 - pm2xxx_charger_check_hw_failure_work); 1066 - 1067 - /* 1068 - * VDD ADC supply needs to be enabled from this driver when there 1069 - * is a charger connected to avoid erroneous BTEMP_HIGH/LOW 1070 - * interrupts during charging 1071 - */ 1072 - pm2->regu = regulator_get(pm2->dev, "vddadc"); 1073 - if (IS_ERR(pm2->regu)) { 1074 - ret = PTR_ERR(pm2->regu); 1075 - dev_err(pm2->dev, "failed to get vddadc regulator\n"); 1076 - goto free_charger_wq; 1077 - } 1078 - 1079 - /* Register AC charger class */ 1080 - pm2->ac_chg.psy = power_supply_register(pm2->dev, &pm2->ac_chg_desc, 1081 - &psy_cfg); 1082 - if (IS_ERR(pm2->ac_chg.psy)) { 1083 - dev_err(pm2->dev, "failed to register AC charger\n"); 1084 - ret = PTR_ERR(pm2->ac_chg.psy); 1085 - goto free_regulator; 1086 - } 1087 - 1088 - /* Register interrupts */ 1089 - ret = request_threaded_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), 1090 - NULL, 1091 - pm2xxx_charger_irq[0].isr, 1092 - pm2->pdata->irq_type | IRQF_ONESHOT, 1093 - pm2xxx_charger_irq[0].name, pm2); 1094 - 1095 - if (ret != 0) { 1096 - dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n", 1097 - pm2xxx_charger_irq[0].name, 1098 - gpio_to_irq(pm2->pdata->gpio_irq_number), ret); 1099 - goto unregister_pm2xxx_charger; 1100 - } 1101 - 1102 - ret = pm_runtime_set_active(pm2->dev); 1103 - if (ret) 1104 - dev_err(pm2->dev, "set active Error\n"); 1105 - 1106 - pm_runtime_enable(pm2->dev); 1107 - pm_runtime_set_autosuspend_delay(pm2->dev, PM2XXX_AUTOSUSPEND_DELAY); 1108 - pm_runtime_use_autosuspend(pm2->dev); 1109 - pm_runtime_resume(pm2->dev); 1110 - 1111 - /* pm interrupt can wake up system */ 1112 - ret = enable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); 1113 - if (ret) { 1114 - dev_err(pm2->dev, "failed to set irq wake\n"); 1115 - goto unregister_pm2xxx_interrupt; 1116 - } 1117 - 1118 - mutex_init(&pm2->lock); 1119 - 1120 - if (gpio_is_valid(pm2->pdata->lpn_gpio)) { 1121 - /* get lpn GPIO from platform data */ 1122 - pm2->lpn_pin = pm2->pdata->lpn_gpio; 1123 - 1124 - /* 1125 - * Charger detection mechanism requires pulling up the LPN pin 1126 - * while i2c communication if Charger is not connected 1127 - * LPN pin of PM2301 is GPIO60 of AB9540 1128 - */ 1129 - ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); 1130 - 1131 - if (ret < 0) { 1132 - dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); 1133 - goto disable_pm2_irq_wake; 1134 - } 1135 - ret = gpio_direction_output(pm2->lpn_pin, 0); 1136 - if (ret < 0) { 1137 - dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n"); 1138 - goto free_gpio; 1139 - } 1140 - set_lpn_pin(pm2); 1141 - } 1142 - 1143 - /* read interrupt registers */ 1144 - for (i = 0; i < PM2XXX_NUM_INT_REG; i++) 1145 - pm2xxx_reg_read(pm2, 1146 - pm2xxx_interrupt_registers[i], 1147 - &val); 1148 - 1149 - ret = pm2xxx_charger_detection(pm2, &val); 1150 - 1151 - if ((ret == 0) && val) { 1152 - pm2->ac.charger_connected = 1; 1153 - ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, 1154 - AB8500_MAIN_CH_DET); 1155 - pm2->ac_conn = true; 1156 - power_supply_changed(pm2->ac_chg.psy); 1157 - sysfs_notify(&pm2->ac_chg.psy->dev.kobj, NULL, "present"); 1158 - } 1159 - 1160 - return 0; 1161 - 1162 - free_gpio: 1163 - if (gpio_is_valid(pm2->lpn_pin)) 1164 - gpio_free(pm2->lpn_pin); 1165 - disable_pm2_irq_wake: 1166 - disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); 1167 - unregister_pm2xxx_interrupt: 1168 - /* disable interrupt */ 1169 - free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); 1170 - unregister_pm2xxx_charger: 1171 - /* unregister power supply */ 1172 - power_supply_unregister(pm2->ac_chg.psy); 1173 - free_regulator: 1174 - /* disable the regulator */ 1175 - regulator_put(pm2->regu); 1176 - free_charger_wq: 1177 - destroy_workqueue(pm2->charger_wq); 1178 - free_device_info: 1179 - kfree(pm2); 1180 - 1181 - return ret; 1182 - } 1183 - 1184 - static int pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) 1185 - { 1186 - struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); 1187 - 1188 - /* Disable pm_runtime */ 1189 - pm_runtime_disable(pm2->dev); 1190 - /* Disable AC charging */ 1191 - pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); 1192 - 1193 - /* Disable wake by pm interrupt */ 1194 - disable_irq_wake(gpio_to_irq(pm2->pdata->gpio_irq_number)); 1195 - 1196 - /* Disable interrupts */ 1197 - free_irq(gpio_to_irq(pm2->pdata->gpio_irq_number), pm2); 1198 - 1199 - /* Delete the work queue */ 1200 - destroy_workqueue(pm2->charger_wq); 1201 - 1202 - flush_scheduled_work(); 1203 - 1204 - /* disable the regulator */ 1205 - regulator_put(pm2->regu); 1206 - 1207 - power_supply_unregister(pm2->ac_chg.psy); 1208 - 1209 - if (gpio_is_valid(pm2->lpn_pin)) 1210 - gpio_free(pm2->lpn_pin); 1211 - 1212 - kfree(pm2); 1213 - 1214 - return 0; 1215 - } 1216 - 1217 - static const struct i2c_device_id pm2xxx_id[] = { 1218 - { "pm2301", 0 }, 1219 - { } 1220 - }; 1221 - 1222 - MODULE_DEVICE_TABLE(i2c, pm2xxx_id); 1223 - 1224 - static struct i2c_driver pm2xxx_charger_driver = { 1225 - .probe = pm2xxx_wall_charger_probe, 1226 - .remove = pm2xxx_wall_charger_remove, 1227 - .driver = { 1228 - .name = "pm2xxx-wall_charger", 1229 - .pm = IS_ENABLED(CONFIG_PM) ? &pm2xxx_pm_ops : NULL, 1230 - }, 1231 - .id_table = pm2xxx_id, 1232 - }; 1233 - 1234 - static int __init pm2xxx_charger_init(void) 1235 - { 1236 - return i2c_add_driver(&pm2xxx_charger_driver); 1237 - } 1238 - 1239 - static void __exit pm2xxx_charger_exit(void) 1240 - { 1241 - i2c_del_driver(&pm2xxx_charger_driver); 1242 - } 1243 - 1244 - device_initcall_sync(pm2xxx_charger_init); 1245 - module_exit(pm2xxx_charger_exit); 1246 - 1247 - MODULE_LICENSE("GPL v2"); 1248 - MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); 1249 - MODULE_DESCRIPTION("PM2xxx charger management driver");
+235
drivers/power/supply/rn5t618_power.c
··· 37 37 #define CHG_STATE_NO_BAT2 13 38 38 #define CHG_STATE_CHG_READY_VUSB 14 39 39 40 + #define GCHGDET_TYPE_MASK 0x30 41 + #define GCHGDET_TYPE_SDP 0x00 42 + #define GCHGDET_TYPE_CDP 0x10 43 + #define GCHGDET_TYPE_DCP 0x20 44 + 40 45 #define FG_ENABLE 1 46 + 47 + /* 48 + * Formula seems accurate for battery current, but for USB current around 70mA 49 + * per step was seen on Kobo Clara HD but all sources show the same formula 50 + * also fur USB current. To avoid accidentially unwanted high currents we stick 51 + * to that formula 52 + */ 53 + #define TO_CUR_REG(x) ((x) / 100000 - 1) 54 + #define FROM_CUR_REG(x) ((((x) & 0x1f) + 1) * 100000) 55 + #define CHG_MIN_CUR 100000 56 + #define CHG_MAX_CUR 1800000 57 + #define ADP_MAX_CUR 2500000 58 + #define USB_MAX_CUR 1400000 59 + 41 60 42 61 struct rn5t618_power_info { 43 62 struct rn5t618 *rn5t618; ··· 67 48 int irq; 68 49 }; 69 50 51 + static enum power_supply_usb_type rn5t618_usb_types[] = { 52 + POWER_SUPPLY_USB_TYPE_SDP, 53 + POWER_SUPPLY_USB_TYPE_DCP, 54 + POWER_SUPPLY_USB_TYPE_CDP, 55 + POWER_SUPPLY_USB_TYPE_UNKNOWN 56 + }; 57 + 70 58 static enum power_supply_property rn5t618_usb_props[] = { 59 + /* input current limit is not very accurate */ 60 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 71 61 POWER_SUPPLY_PROP_STATUS, 62 + POWER_SUPPLY_PROP_USB_TYPE, 72 63 POWER_SUPPLY_PROP_ONLINE, 73 64 }; 74 65 75 66 static enum power_supply_property rn5t618_adp_props[] = { 67 + /* input current limit is not very accurate */ 68 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 76 69 POWER_SUPPLY_PROP_STATUS, 77 70 POWER_SUPPLY_PROP_ONLINE, 78 71 }; ··· 100 69 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW, 101 70 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW, 102 71 POWER_SUPPLY_PROP_TECHNOLOGY, 72 + POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, 103 73 POWER_SUPPLY_PROP_CHARGE_FULL, 104 74 POWER_SUPPLY_PROP_CHARGE_NOW, 105 75 }; ··· 290 258 return 0; 291 259 } 292 260 261 + static int rn5t618_battery_set_current_limit(struct rn5t618_power_info *info, 262 + const union power_supply_propval *val) 263 + { 264 + if (val->intval < CHG_MIN_CUR) 265 + return -EINVAL; 266 + 267 + if (val->intval >= CHG_MAX_CUR) 268 + return -EINVAL; 269 + 270 + return regmap_update_bits(info->rn5t618->regmap, 271 + RN5T618_CHGISET, 272 + 0x1F, TO_CUR_REG(val->intval)); 273 + } 274 + 275 + static int rn5t618_battery_get_current_limit(struct rn5t618_power_info *info, 276 + union power_supply_propval *val) 277 + { 278 + unsigned int regval; 279 + int ret; 280 + 281 + ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGISET, 282 + &regval); 283 + if (ret < 0) 284 + return ret; 285 + 286 + val->intval = FROM_CUR_REG(regval); 287 + 288 + return 0; 289 + } 290 + 293 291 static int rn5t618_battery_charge_full(struct rn5t618_power_info *info, 294 292 union power_supply_propval *val) 295 293 { ··· 385 323 case POWER_SUPPLY_PROP_TECHNOLOGY: 386 324 val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 387 325 break; 326 + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 327 + ret = rn5t618_battery_get_current_limit(info, val); 328 + break; 388 329 case POWER_SUPPLY_PROP_CHARGE_FULL: 389 330 ret = rn5t618_battery_charge_full(info, val); 390 331 break; ··· 401 336 return ret; 402 337 } 403 338 339 + static int rn5t618_battery_set_property(struct power_supply *psy, 340 + enum power_supply_property psp, 341 + const union power_supply_propval *val) 342 + { 343 + struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 344 + 345 + switch (psp) { 346 + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 347 + return rn5t618_battery_set_current_limit(info, val); 348 + default: 349 + return -EINVAL; 350 + } 351 + } 352 + 353 + static int rn5t618_battery_property_is_writeable(struct power_supply *psy, 354 + enum power_supply_property psp) 355 + { 356 + switch (psp) { 357 + case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT: 358 + return true; 359 + default: 360 + return false; 361 + } 362 + } 363 + 404 364 static int rn5t618_adp_get_property(struct power_supply *psy, 405 365 enum power_supply_property psp, 406 366 union power_supply_propval *val) 407 367 { 408 368 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 409 369 unsigned int chgstate; 370 + unsigned int regval; 410 371 bool online; 411 372 int ret; 412 373 ··· 456 365 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 457 366 458 367 break; 368 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 369 + ret = regmap_read(info->rn5t618->regmap, 370 + RN5T618_REGISET1, &regval); 371 + if (ret < 0) 372 + return ret; 373 + 374 + val->intval = FROM_CUR_REG(regval); 375 + break; 459 376 default: 460 377 return -EINVAL; 378 + } 379 + 380 + return 0; 381 + } 382 + 383 + static int rn5t618_adp_set_property(struct power_supply *psy, 384 + enum power_supply_property psp, 385 + const union power_supply_propval *val) 386 + { 387 + struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 388 + int ret; 389 + 390 + switch (psp) { 391 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 392 + if (val->intval > ADP_MAX_CUR) 393 + return -EINVAL; 394 + 395 + if (val->intval < CHG_MIN_CUR) 396 + return -EINVAL; 397 + 398 + ret = regmap_write(info->rn5t618->regmap, RN5T618_REGISET1, 399 + TO_CUR_REG(val->intval)); 400 + if (ret < 0) 401 + return ret; 402 + 403 + break; 404 + default: 405 + return -EINVAL; 406 + } 407 + 408 + return 0; 409 + } 410 + 411 + static int rn5t618_adp_property_is_writeable(struct power_supply *psy, 412 + enum power_supply_property psp) 413 + { 414 + switch (psp) { 415 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 416 + return true; 417 + default: 418 + return false; 419 + } 420 + } 421 + 422 + static int rc5t619_usb_get_type(struct rn5t618_power_info *info, 423 + union power_supply_propval *val) 424 + { 425 + unsigned int regval; 426 + int ret; 427 + 428 + ret = regmap_read(info->rn5t618->regmap, RN5T618_GCHGDET, &regval); 429 + if (ret < 0) 430 + return ret; 431 + 432 + switch (regval & GCHGDET_TYPE_MASK) { 433 + case GCHGDET_TYPE_SDP: 434 + val->intval = POWER_SUPPLY_USB_TYPE_SDP; 435 + break; 436 + case GCHGDET_TYPE_CDP: 437 + val->intval = POWER_SUPPLY_USB_TYPE_CDP; 438 + break; 439 + case GCHGDET_TYPE_DCP: 440 + val->intval = POWER_SUPPLY_USB_TYPE_DCP; 441 + break; 442 + default: 443 + val->intval = POWER_SUPPLY_USB_TYPE_UNKNOWN; 461 444 } 462 445 463 446 return 0; ··· 543 378 { 544 379 struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 545 380 unsigned int chgstate; 381 + unsigned int regval; 546 382 bool online; 547 383 int ret; 548 384 ··· 567 401 val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 568 402 569 403 break; 404 + case POWER_SUPPLY_PROP_USB_TYPE: 405 + if (!online || (info->rn5t618->variant != RC5T619)) 406 + return -ENODATA; 407 + 408 + return rc5t619_usb_get_type(info, val); 409 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 410 + ret = regmap_read(info->rn5t618->regmap, RN5T618_CHGCTL1, 411 + &regval); 412 + if (ret < 0) 413 + return ret; 414 + 415 + val->intval = 0; 416 + if (regval & 2) { 417 + ret = regmap_read(info->rn5t618->regmap, 418 + RN5T618_REGISET2, 419 + &regval); 420 + if (ret < 0) 421 + return ret; 422 + 423 + val->intval = FROM_CUR_REG(regval); 424 + } 425 + break; 570 426 default: 571 427 return -EINVAL; 572 428 } 573 429 574 430 return 0; 431 + } 432 + 433 + static int rn5t618_usb_set_property(struct power_supply *psy, 434 + enum power_supply_property psp, 435 + const union power_supply_propval *val) 436 + { 437 + struct rn5t618_power_info *info = power_supply_get_drvdata(psy); 438 + int ret; 439 + 440 + switch (psp) { 441 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 442 + if (val->intval > USB_MAX_CUR) 443 + return -EINVAL; 444 + 445 + if (val->intval < CHG_MIN_CUR) 446 + return -EINVAL; 447 + 448 + ret = regmap_write(info->rn5t618->regmap, RN5T618_REGISET2, 449 + 0xE0 | TO_CUR_REG(val->intval)); 450 + if (ret < 0) 451 + return ret; 452 + 453 + break; 454 + default: 455 + return -EINVAL; 456 + } 457 + 458 + return 0; 459 + } 460 + 461 + static int rn5t618_usb_property_is_writeable(struct power_supply *psy, 462 + enum power_supply_property psp) 463 + { 464 + switch (psp) { 465 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 466 + return true; 467 + default: 468 + return false; 469 + } 575 470 } 576 471 577 472 static const struct power_supply_desc rn5t618_battery_desc = { ··· 641 414 .properties = rn5t618_battery_props, 642 415 .num_properties = ARRAY_SIZE(rn5t618_battery_props), 643 416 .get_property = rn5t618_battery_get_property, 417 + .set_property = rn5t618_battery_set_property, 418 + .property_is_writeable = rn5t618_battery_property_is_writeable, 644 419 }; 645 420 646 421 static const struct power_supply_desc rn5t618_adp_desc = { ··· 651 422 .properties = rn5t618_adp_props, 652 423 .num_properties = ARRAY_SIZE(rn5t618_adp_props), 653 424 .get_property = rn5t618_adp_get_property, 425 + .set_property = rn5t618_adp_set_property, 426 + .property_is_writeable = rn5t618_adp_property_is_writeable, 654 427 }; 655 428 656 429 static const struct power_supply_desc rn5t618_usb_desc = { 657 430 .name = "rn5t618-usb", 658 431 .type = POWER_SUPPLY_TYPE_USB, 432 + .usb_types = rn5t618_usb_types, 433 + .num_usb_types = ARRAY_SIZE(rn5t618_usb_types), 659 434 .properties = rn5t618_usb_props, 660 435 .num_properties = ARRAY_SIZE(rn5t618_usb_props), 661 436 .get_property = rn5t618_usb_get_property, 437 + .set_property = rn5t618_usb_set_property, 438 + .property_is_writeable = rn5t618_usb_property_is_writeable, 662 439 }; 663 440 664 441 static irqreturn_t rn5t618_charger_irq(int irq, void *data)
+7
drivers/power/supply/rt5033_battery.c
··· 164 164 }; 165 165 MODULE_DEVICE_TABLE(i2c, rt5033_battery_id); 166 166 167 + static const struct of_device_id rt5033_battery_of_match[] = { 168 + { .compatible = "richtek,rt5033-battery", }, 169 + { } 170 + }; 171 + MODULE_DEVICE_TABLE(of, rt5033_battery_of_match); 172 + 167 173 static struct i2c_driver rt5033_battery_driver = { 168 174 .driver = { 169 175 .name = "rt5033-battery", 176 + .of_match_table = rt5033_battery_of_match, 170 177 }, 171 178 .probe = rt5033_battery_probe, 172 179 .remove = rt5033_battery_remove,
+95 -58
drivers/power/supply/sbs-battery.c
··· 189 189 /* Supports special manufacturer commands from TI BQ20Z65 and BQ20Z75 IC. */ 190 190 #define SBS_FLAGS_TI_BQ20ZX5 BIT(0) 191 191 192 + static const enum power_supply_property string_properties[] = { 193 + POWER_SUPPLY_PROP_TECHNOLOGY, 194 + POWER_SUPPLY_PROP_MANUFACTURER, 195 + POWER_SUPPLY_PROP_MODEL_NAME, 196 + }; 197 + 198 + #define NR_STRING_BUFFERS ARRAY_SIZE(string_properties) 199 + 192 200 struct sbs_info { 193 201 struct i2c_client *client; 194 202 struct power_supply *power_supply; ··· 210 202 struct delayed_work work; 211 203 struct mutex mode_lock; 212 204 u32 flags; 205 + int technology; 206 + char strings[NR_STRING_BUFFERS][I2C_SMBUS_BLOCK_MAX + 1]; 213 207 }; 214 208 215 - static char model_name[I2C_SMBUS_BLOCK_MAX + 1]; 216 - static char manufacturer[I2C_SMBUS_BLOCK_MAX + 1]; 217 - static char chemistry[I2C_SMBUS_BLOCK_MAX + 1]; 209 + static char *sbs_get_string_buf(struct sbs_info *chip, 210 + enum power_supply_property psp) 211 + { 212 + int i = 0; 213 + 214 + for (i = 0; i < NR_STRING_BUFFERS; i++) 215 + if (string_properties[i] == psp) 216 + return chip->strings[i]; 217 + 218 + return ERR_PTR(-EINVAL); 219 + } 220 + 221 + static void sbs_invalidate_cached_props(struct sbs_info *chip) 222 + { 223 + int i = 0; 224 + 225 + chip->technology = -1; 226 + 227 + for (i = 0; i < NR_STRING_BUFFERS; i++) 228 + chip->strings[i][0] = 0; 229 + } 230 + 218 231 static bool force_load; 219 232 220 233 static int sbs_read_word_data(struct i2c_client *client, u8 address); ··· 273 244 chip->is_present = false; 274 245 /* Disable PEC when no device is present */ 275 246 client->flags &= ~I2C_CLIENT_PEC; 247 + sbs_invalidate_cached_props(chip); 276 248 return 0; 277 249 } 278 250 ··· 670 640 return 0; 671 641 } 672 642 673 - static int sbs_get_battery_string_property(struct i2c_client *client, 674 - int reg_offset, enum power_supply_property psp, char *val) 643 + static int sbs_get_property_index(struct i2c_client *client, 644 + enum power_supply_property psp) 675 645 { 676 - s32 ret; 646 + int count; 677 647 678 - ret = sbs_read_string_data(client, sbs_data[reg_offset].addr, val); 648 + for (count = 0; count < ARRAY_SIZE(sbs_data); count++) 649 + if (psp == sbs_data[count].psp) 650 + return count; 679 651 680 - if (ret < 0) 681 - return ret; 652 + dev_warn(&client->dev, 653 + "%s: Invalid Property - %d\n", __func__, psp); 682 654 683 - return 0; 655 + return -EINVAL; 656 + } 657 + 658 + static const char *sbs_get_constant_string(struct sbs_info *chip, 659 + enum power_supply_property psp) 660 + { 661 + int ret; 662 + char *buf; 663 + u8 addr; 664 + 665 + buf = sbs_get_string_buf(chip, psp); 666 + if (IS_ERR(buf)) 667 + return buf; 668 + 669 + if (!buf[0]) { 670 + ret = sbs_get_property_index(chip->client, psp); 671 + if (ret < 0) 672 + return ERR_PTR(ret); 673 + 674 + addr = sbs_data[ret].addr; 675 + 676 + ret = sbs_read_string_data(chip->client, addr, buf); 677 + if (ret < 0) 678 + return ERR_PTR(ret); 679 + } 680 + 681 + return buf; 684 682 } 685 683 686 684 static void sbs_unit_adjustment(struct i2c_client *client, ··· 831 773 return 0; 832 774 } 833 775 834 - static int sbs_get_property_index(struct i2c_client *client, 835 - enum power_supply_property psp) 836 - { 837 - int count; 838 - for (count = 0; count < ARRAY_SIZE(sbs_data); count++) 839 - if (psp == sbs_data[count].psp) 840 - return count; 841 - 842 - dev_warn(&client->dev, 843 - "%s: Invalid Property - %d\n", __func__, psp); 844 - 845 - return -EINVAL; 846 - } 847 - 848 - static int sbs_get_chemistry(struct i2c_client *client, 776 + static int sbs_get_chemistry(struct sbs_info *chip, 849 777 union power_supply_propval *val) 850 778 { 851 - enum power_supply_property psp = POWER_SUPPLY_PROP_TECHNOLOGY; 852 - int ret; 779 + const char *chemistry; 853 780 854 - ret = sbs_get_property_index(client, psp); 855 - if (ret < 0) 856 - return ret; 781 + if (chip->technology != -1) { 782 + val->intval = chip->technology; 783 + return 0; 784 + } 857 785 858 - ret = sbs_get_battery_string_property(client, ret, psp, 859 - chemistry); 860 - if (ret < 0) 861 - return ret; 786 + chemistry = sbs_get_constant_string(chip, POWER_SUPPLY_PROP_TECHNOLOGY); 787 + 788 + if (IS_ERR(chemistry)) 789 + return PTR_ERR(chemistry); 862 790 863 791 if (!strncasecmp(chemistry, "LION", 4)) 864 - val->intval = POWER_SUPPLY_TECHNOLOGY_LION; 792 + chip->technology = POWER_SUPPLY_TECHNOLOGY_LION; 865 793 else if (!strncasecmp(chemistry, "LiP", 3)) 866 - val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO; 794 + chip->technology = POWER_SUPPLY_TECHNOLOGY_LIPO; 867 795 else if (!strncasecmp(chemistry, "NiCd", 4)) 868 - val->intval = POWER_SUPPLY_TECHNOLOGY_NiCd; 796 + chip->technology = POWER_SUPPLY_TECHNOLOGY_NiCd; 869 797 else if (!strncasecmp(chemistry, "NiMH", 4)) 870 - val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH; 798 + chip->technology = POWER_SUPPLY_TECHNOLOGY_NiMH; 871 799 else 872 - val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 800 + chip->technology = POWER_SUPPLY_TECHNOLOGY_UNKNOWN; 873 801 874 - if (val->intval == POWER_SUPPLY_TECHNOLOGY_UNKNOWN) 875 - dev_warn(&client->dev, "Unknown chemistry: %s\n", chemistry); 802 + if (chip->technology == POWER_SUPPLY_TECHNOLOGY_UNKNOWN) 803 + dev_warn(&chip->client->dev, "Unknown chemistry: %s\n", chemistry); 804 + 805 + val->intval = chip->technology; 876 806 877 807 return 0; 878 808 } ··· 904 858 int ret = 0; 905 859 struct sbs_info *chip = power_supply_get_drvdata(psy); 906 860 struct i2c_client *client = chip->client; 861 + const char *str; 907 862 908 863 if (chip->gpio_detect) { 909 864 ret = gpiod_get_value_cansleep(chip->gpio_detect); ··· 930 883 break; 931 884 932 885 case POWER_SUPPLY_PROP_TECHNOLOGY: 933 - ret = sbs_get_chemistry(client, val); 886 + ret = sbs_get_chemistry(chip, val); 934 887 if (ret < 0) 935 888 break; 936 889 ··· 982 935 break; 983 936 984 937 case POWER_SUPPLY_PROP_MODEL_NAME: 985 - ret = sbs_get_property_index(client, psp); 986 - if (ret < 0) 987 - break; 988 - 989 - ret = sbs_get_battery_string_property(client, ret, psp, 990 - model_name); 991 - val->strval = model_name; 992 - break; 993 - 994 938 case POWER_SUPPLY_PROP_MANUFACTURER: 995 - ret = sbs_get_property_index(client, psp); 996 - if (ret < 0) 997 - break; 998 - 999 - ret = sbs_get_battery_string_property(client, ret, psp, 1000 - manufacturer); 1001 - val->strval = manufacturer; 939 + str = sbs_get_constant_string(chip, psp); 940 + if (IS_ERR(str)) 941 + ret = PTR_ERR(str); 942 + else 943 + val->strval = str; 1002 944 break; 1003 945 1004 946 case POWER_SUPPLY_PROP_MANUFACTURE_YEAR: ··· 1134 1098 psy_cfg.of_node = client->dev.of_node; 1135 1099 psy_cfg.drv_data = chip; 1136 1100 chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; 1101 + sbs_invalidate_cached_props(chip); 1137 1102 mutex_init(&chip->mode_lock); 1138 1103 1139 1104 /* use pdata if available, fall back to DT properties,
+1
drivers/power/supply/sc2731_charger.c
··· 524 524 { .compatible = "sprd,sc2731-charger", }, 525 525 { } 526 526 }; 527 + MODULE_DEVICE_TABLE(of, sc2731_charger_of_match); 527 528 528 529 static struct platform_driver sc2731_charger_driver = { 529 530 .driver = {
+1
drivers/power/supply/sc27xx_fuel_gauge.c
··· 1342 1342 { .compatible = "sprd,sc2731-fgu", }, 1343 1343 { } 1344 1344 }; 1345 + MODULE_DEVICE_TABLE(of, sc27xx_fgu_of_match); 1345 1346 1346 1347 static struct platform_driver sc27xx_fgu_driver = { 1347 1348 .probe = sc27xx_fgu_probe,
-1
drivers/power/supply/smb347-charger.c
··· 10 10 11 11 #include <linux/delay.h> 12 12 #include <linux/err.h> 13 - #include <linux/gpio.h> 14 13 #include <linux/kernel.h> 15 14 #include <linux/module.h> 16 15 #include <linux/init.h>
+12 -2
drivers/power/supply/surface_battery.c
··· 345 345 struct spwr_battery_device *bat = container_of(nf, struct spwr_battery_device, notif); 346 346 int status; 347 347 348 + /* 349 + * We cannot use strict matching when registering the notifier as the 350 + * EC expects us to register it against instance ID 0. Strict matching 351 + * would thus drop events, as those may have non-zero instance IDs in 352 + * this subsystem. So we need to check the instance ID of the event 353 + * here manually. 354 + */ 355 + if (event->instance_id != bat->sdev->uid.instance) 356 + return 0; 357 + 348 358 dev_dbg(&bat->sdev->dev, "power event (cid = %#04x, iid = %#04x, tid = %#04x)\n", 349 359 event->command_id, event->instance_id, event->target_id); 350 360 ··· 730 720 bat->notif.base.fn = spwr_notify_bat; 731 721 bat->notif.event.reg = registry; 732 722 bat->notif.event.id.target_category = sdev->uid.category; 733 - bat->notif.event.id.instance = 0; 734 - bat->notif.event.mask = SSAM_EVENT_MASK_STRICT; 723 + bat->notif.event.id.instance = 0; /* need to register with instance 0 */ 724 + bat->notif.event.mask = SSAM_EVENT_MASK_TARGET; 735 725 bat->notif.event.flags = SSAM_EVENT_SEQUENCED; 736 726 737 727 bat->psy_desc.name = bat->name;
+1 -1
drivers/power/supply/surface_charger.c
··· 66 66 67 67 static int spwr_ac_update_unlocked(struct spwr_ac_device *ac) 68 68 { 69 - u32 old = ac->state; 69 + __le32 old = ac->state; 70 70 int status; 71 71 72 72 lockdep_assert_held(&ac->lock);
-16
include/linux/max17040_battery.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) 2009 Samsung Electronics 4 - * Minkyu Kang <mk7.kang@samsung.com> 5 - */ 6 - 7 - #ifndef __MAX17040_BATTERY_H_ 8 - #define __MAX17040_BATTERY_H_ 9 - 10 - struct max17040_platform_data { 11 - int (*battery_online)(void); 12 - int (*charger_online)(void); 13 - int (*charger_enable)(void); 14 - }; 15 - 16 - #endif
-48
include/linux/pm2301_charger.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * PM2301 charger driver. 4 - * 5 - * Copyright (C) 2012 ST Ericsson Corporation 6 - * 7 - * Contact: Olivier LAUNAY (olivier.launay@stericsson.com 8 - */ 9 - 10 - #ifndef __LINUX_PM2301_H 11 - #define __LINUX_PM2301_H 12 - 13 - /** 14 - * struct pm2xxx_bm_charger_parameters - Charger specific parameters 15 - * @ac_volt_max: maximum allowed AC charger voltage in mV 16 - * @ac_curr_max: maximum allowed AC charger current in mA 17 - */ 18 - struct pm2xxx_bm_charger_parameters { 19 - int ac_volt_max; 20 - int ac_curr_max; 21 - }; 22 - 23 - /** 24 - * struct pm2xxx_bm_data - pm2xxx battery management data 25 - * @enable_overshoot flag to enable VBAT overshoot control 26 - * @chg_params charger parameters 27 - */ 28 - struct pm2xxx_bm_data { 29 - bool enable_overshoot; 30 - const struct pm2xxx_bm_charger_parameters *chg_params; 31 - }; 32 - 33 - struct pm2xxx_charger_platform_data { 34 - char **supplied_to; 35 - size_t num_supplicants; 36 - int i2c_bus; 37 - const char *label; 38 - int gpio_irq_number; 39 - unsigned int lpn_gpio; 40 - int irq_type; 41 - }; 42 - 43 - struct pm2xxx_platform_data { 44 - struct pm2xxx_charger_platform_data *wall_charger; 45 - struct pm2xxx_bm_data *battery; 46 - }; 47 - 48 - #endif /* __LINUX_PM2301_H */
-16
include/linux/power/ab8500.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * Copyright (C) ST-Ericsson 2013 4 - * Author: Hongbo Zhang <hongbo.zhang@linaro.com> 5 - */ 6 - 7 - #ifndef PWR_AB8500_H 8 - #define PWR_AB8500_H 9 - 10 - extern const struct abx500_res_to_temp ab8500_temp_tbl_a_thermistor[]; 11 - extern const int ab8500_temp_tbl_a_size; 12 - 13 - extern const struct abx500_res_to_temp ab8500_temp_tbl_b_thermistor[]; 14 - extern const int ab8500_temp_tbl_b_size; 15 - 16 - #endif /* PWR_AB8500_H */