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

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull power supply and reset updates from Sebastian Reichel:
"Power-supply core:
- introduce power_supply_show_enum_with_available() helper
- change usb_types from an array into a bitmask
- fix early usage of power_supply_property_is_writeable() resulting
in sysfs files not being writable
- fix missing temp1_max_alarm attribute in power-supply's hwmon
devices

Drivers:
- max1720x: expose nvmem device
- brcmstb: cleanup driver to use latest APIs
- max77693: expose input and charging current limit
- max17042_battery: fix state of charge reading for devices without
current sensing
- axp20x_battery: add AXP717 support
- axp20x_battery: fix min/max voltage properties
- axp20x_usb_power: add AXP717 support
- axp20x_usb_power: add DT based input current limit

Documentation updates

Misc minor cleanups and fixes"

* tag 'for-v6.12' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (38 commits)
power: supply: hwmon: Fix missing temp1_max_alarm attribute
power: supply: Drop use_cnt check from power_supply_property_is_writeable()
power: supply: ab8500: Constify struct kobj_type
power: supply: max1720x: fix a double free on error in probe()
power: supply: axp20x_battery: add support for AXP717
power: supply: axp20x_usb_power: Add support for AXP717
dt-bindings: power: supply: axp20x: Add AXP717 compatible
dt-bindings: power: supply: axp20x: Add AXP717 compatible
power: supply: axp20x_usb_power: Fix spelling mistake "reqested" -> "requested"
power: supply: Change usb_types from an array into a bitmask
power: supply: sysfs: Move power_supply_show_enum_with_available() up
power: supply: sysfs: Add power_supply_show_enum_with_available() helper
power: supply: rt9467-charger: Remove "usb_type" property write support
power: supply: ucs1002: Adjust ucs1002_set_usb_type() to accept string values
power: supply: "usb_type" property may be written to
power: supply: max1720x: add read support for nvmem
mfd: axp20x: Add ADC, BAT, and USB cells for AXP717
power: supply: core: constify psy_tzd_ops
power: reset: brcmstb: Do not go into infinite loop if reset fails
power: reset: brcmstb: Use devm_register_sys_off_handler()
...

+1433 -444
+33 -12
Documentation/ABI/testing/sysfs-class-power
··· 377 377 Date: July 2009 378 378 Contact: linux-pm@vger.kernel.org 379 379 Description: 380 - Represents the type of charging currently being applied to the 381 - battery. "Trickle", "Fast", and "Standard" all mean different 382 - charging speeds. "Adaptive" means that the charger uses some 383 - algorithm to adjust the charge rate dynamically, without 384 - any user configuration required. "Custom" means that the charger 385 - uses the charge_control_* properties as configuration for some 386 - different algorithm. "Long Life" means the charger reduces its 387 - charging rate in order to prolong the battery health. "Bypass" 388 - means the charger bypasses the charging path around the 389 - integrated converter allowing for a "smart" wall adaptor to 390 - perform the power conversion externally. 380 + Select the charging algorithm to use for a battery. 381 + 382 + Standard: 383 + Fully charge the battery at a moderate rate. 384 + Fast: 385 + Quickly charge the battery using fast-charge 386 + technology. This is typically harder on the battery 387 + than standard charging and may lower its lifespan. 388 + Trickle: 389 + Users who primarily operate the system while 390 + plugged into an external power source can extend 391 + battery life with this mode. Vendor tooling may 392 + call this "Primarily AC Use". 393 + Adaptive: 394 + Automatically optimize battery charge rate based 395 + on typical usage pattern. 396 + Custom: 397 + Use the charge_control_* properties to determine 398 + when to start and stop charging. Advanced users 399 + can use this to drastically extend battery life. 400 + Long Life: 401 + The charger reduces its charging rate in order to 402 + prolong the battery health. 403 + Bypass: 404 + The charger bypasses the charging path around the 405 + integrated converter allowing for a "smart" wall 406 + adaptor to perform the power conversion externally. 391 407 392 408 Access: Read, Write 393 409 ··· 608 592 the supply, for example it can show if USB-PD capable source 609 593 is attached. 610 594 611 - Access: Read-Only 595 + Access: For power-supplies which consume USB power such 596 + as battery charger chips, this indicates the type of 597 + the connected USB power source and is Read-Only. 598 + 599 + For power-supplies which act as a USB power-source such as 600 + e.g. the UCS1002 USB Port Power Controller this is writable. 612 601 613 602 Valid values: 614 603 "Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD",
+6
Documentation/devicetree/bindings/power/supply/sc27xx-fg.yaml
··· 27 27 battery-detect-gpios: 28 28 maxItems: 1 29 29 30 + interrupts: 31 + maxItems: 1 32 + 30 33 io-channels: 31 34 items: 32 35 - description: Battery Temperature ADC ··· 56 53 - compatible 57 54 - reg 58 55 - battery-detect-gpios 56 + - interrupts 59 57 - io-channels 60 58 - io-channel-names 61 59 - nvmem-cells ··· 92 88 compatible = "sprd,sc2731-fgu"; 93 89 reg = <0xa00>; 94 90 battery-detect-gpios = <&pmic_eic 9 GPIO_ACTIVE_HIGH>; 91 + interrupt-parent = <&sc2731_pmic>; 92 + interrupts = <4>; 95 93 io-channels = <&pmic_adc 5>, <&pmic_adc 14>; 96 94 io-channel-names = "bat-temp", "charge-vol"; 97 95 nvmem-cells = <&fgu_calib>;
+7
Documentation/devicetree/bindings/power/supply/x-powers,axp20x-battery-power-supply.yaml
··· 23 23 - const: x-powers,axp202-battery-power-supply 24 24 - const: x-powers,axp209-battery-power-supply 25 25 - const: x-powers,axp221-battery-power-supply 26 + - const: x-powers,axp717-battery-power-supply 26 27 - items: 27 28 - const: x-powers,axp803-battery-power-supply 28 29 - const: x-powers,axp813-battery-power-supply 29 30 - const: x-powers,axp813-battery-power-supply 31 + 32 + monitored-battery: 33 + description: 34 + Specifies the phandle of an optional simple-battery connected to 35 + this gauge. 36 + $ref: /schemas/types.yaml#/definitions/phandle 30 37 31 38 required: 32 39 - compatible
+69 -3
Documentation/devicetree/bindings/power/supply/x-powers,axp20x-usb-power-supply.yaml
··· 15 15 - Chen-Yu Tsai <wens@csie.org> 16 16 - Sebastian Reichel <sre@kernel.org> 17 17 18 - allOf: 19 - - $ref: power-supply.yaml# 20 - 21 18 properties: 22 19 compatible: 23 20 oneOf: ··· 23 26 - x-powers,axp202-usb-power-supply 24 27 - x-powers,axp221-usb-power-supply 25 28 - x-powers,axp223-usb-power-supply 29 + - x-powers,axp717-usb-power-supply 26 30 - x-powers,axp813-usb-power-supply 27 31 - items: 28 32 - const: x-powers,axp803-usb-power-supply 29 33 - const: x-powers,axp813-usb-power-supply 30 34 35 + input-current-limit-microamp: 36 + description: 37 + Optional value to clamp the maximum input current limit to for 38 + the device. If omitted, the programmed value from the EFUSE will 39 + be used. 40 + minimum: 100000 41 + maximum: 4000000 31 42 32 43 required: 33 44 - compatible 45 + 46 + allOf: 47 + - $ref: power-supply.yaml# 48 + - if: 49 + properties: 50 + compatible: 51 + contains: 52 + enum: 53 + - x-powers,axp192-usb-power-supply 54 + then: 55 + properties: 56 + input-current-limit-microamp: 57 + enum: [100000, 500000] 58 + 59 + - if: 60 + properties: 61 + compatible: 62 + contains: 63 + enum: 64 + - x-powers,axp202-usb-power-supply 65 + - x-powers,axp223-usb-power-supply 66 + then: 67 + properties: 68 + input-current-limit-microamp: 69 + enum: [100000, 500000, 900000] 70 + 71 + - if: 72 + properties: 73 + compatible: 74 + contains: 75 + enum: 76 + - x-powers,axp221-usb-power-supply 77 + then: 78 + properties: 79 + input-current-limit-microamp: 80 + enum: [500000, 900000] 81 + 82 + - if: 83 + properties: 84 + compatible: 85 + contains: 86 + enum: 87 + - x-powers,axp717-usb-power-supply 88 + then: 89 + properties: 90 + input-current-limit-microamp: 91 + description: Maximum input current in increments of 50000 uA. 92 + minimum: 100000 93 + maximum: 3250000 94 + 95 + - if: 96 + properties: 97 + compatible: 98 + contains: 99 + enum: 100 + - x-powers,axp813-usb-power-supply 101 + then: 102 + properties: 103 + input-current-limit-microamp: 104 + enum: [100000, 500000, 900000, 1500000, 2000000, 2500000, 105 + 3000000, 3500000, 4000000] 34 106 35 107 additionalProperties: false
+5 -10
drivers/extcon/extcon-intel-cht-wc.c
··· 461 461 return 0; 462 462 } 463 463 464 - static const enum power_supply_usb_type cht_wc_extcon_psy_usb_types[] = { 465 - POWER_SUPPLY_USB_TYPE_SDP, 466 - POWER_SUPPLY_USB_TYPE_CDP, 467 - POWER_SUPPLY_USB_TYPE_DCP, 468 - POWER_SUPPLY_USB_TYPE_ACA, 469 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 470 - }; 471 - 472 464 static const enum power_supply_property cht_wc_extcon_psy_props[] = { 473 465 POWER_SUPPLY_PROP_USB_TYPE, 474 466 POWER_SUPPLY_PROP_ONLINE, ··· 469 477 static const struct power_supply_desc cht_wc_extcon_psy_desc = { 470 478 .name = "cht_wcove_pwrsrc", 471 479 .type = POWER_SUPPLY_TYPE_USB, 472 - .usb_types = cht_wc_extcon_psy_usb_types, 473 - .num_usb_types = ARRAY_SIZE(cht_wc_extcon_psy_usb_types), 480 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 481 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 482 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 483 + BIT(POWER_SUPPLY_USB_TYPE_ACA) | 484 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 474 485 .properties = cht_wc_extcon_psy_props, 475 486 .num_properties = ARRAY_SIZE(cht_wc_extcon_psy_props), 476 487 .get_property = cht_wc_extcon_psy_get_prop,
+24 -3
drivers/mfd/axp20x.c
··· 209 209 }; 210 210 211 211 static const struct regmap_range axp717_writeable_ranges[] = { 212 - regmap_reg_range(AXP717_MODULE_EN_CONTROL_2, AXP717_MODULE_EN_CONTROL_2), 213 - regmap_reg_range(AXP717_BOOST_CONTROL, AXP717_BOOST_CONTROL), 212 + regmap_reg_range(AXP717_PMU_FAULT, AXP717_MODULE_EN_CONTROL_1), 213 + regmap_reg_range(AXP717_MIN_SYS_V_CONTROL, AXP717_BOOST_CONTROL), 214 + regmap_reg_range(AXP717_VSYS_V_POWEROFF, AXP717_VSYS_V_POWEROFF), 214 215 regmap_reg_range(AXP717_IRQ0_EN, AXP717_IRQ4_EN), 215 216 regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE), 217 + regmap_reg_range(AXP717_ICC_CHG_SET, AXP717_CV_CHG_SET), 216 218 regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL), 219 + regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL), 220 + regmap_reg_range(AXP717_ADC_DATA_SEL, AXP717_ADC_DATA_SEL), 217 221 }; 218 222 219 223 static const struct regmap_range axp717_volatile_ranges[] = { 224 + regmap_reg_range(AXP717_ON_INDICATE, AXP717_PMU_FAULT), 220 225 regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE), 226 + regmap_reg_range(AXP717_BATT_PERCENT_DATA, AXP717_BATT_PERCENT_DATA), 227 + regmap_reg_range(AXP717_BATT_V_H, AXP717_BATT_CHRG_I_L), 228 + regmap_reg_range(AXP717_ADC_DATA_H, AXP717_ADC_DATA_L), 221 229 }; 222 230 223 231 static const struct regmap_access_table axp717_writeable_table = { ··· 316 308 static const struct resource axp22x_usb_power_supply_resources[] = { 317 309 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 318 310 DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 311 + }; 312 + 313 + static const struct resource axp717_usb_power_supply_resources[] = { 314 + DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_OVER_V, "VBUS_OVER_V"), 315 + DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"), 316 + DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"), 319 317 }; 320 318 321 319 /* AXP803 and AXP813/AXP818 share the same interrupts */ ··· 438 424 .val_bits = 8, 439 425 .wr_table = &axp717_writeable_table, 440 426 .volatile_table = &axp717_volatile_table, 441 - .max_register = AXP717_CPUSLDO_CONTROL, 427 + .max_register = AXP717_ADC_DATA_L, 442 428 .cache_type = REGCACHE_MAPLE, 443 429 }; 444 430 ··· 1040 1026 static struct mfd_cell axp717_cells[] = { 1041 1027 MFD_CELL_NAME("axp20x-regulator"), 1042 1028 MFD_CELL_RES("axp20x-pek", axp717_pek_resources), 1029 + MFD_CELL_OF("axp717-adc", 1030 + NULL, NULL, 0, 0, "x-powers,axp717-adc"), 1031 + MFD_CELL_OF("axp20x-usb-power-supply", 1032 + axp717_usb_power_supply_resources, NULL, 0, 0, 1033 + "x-powers,axp717-usb-power-supply"), 1034 + MFD_CELL_OF("axp20x-battery-power-supply", 1035 + NULL, NULL, 0, 0, "x-powers,axp717-battery-power-supply"), 1043 1036 }; 1044 1037 1045 1038 static const struct resource axp288_adc_resources[] = {
+3 -8
drivers/phy/ti/phy-tusb1210.c
··· 411 411 return 0; 412 412 } 413 413 414 - static const enum power_supply_usb_type tusb1210_psy_usb_types[] = { 415 - POWER_SUPPLY_USB_TYPE_SDP, 416 - POWER_SUPPLY_USB_TYPE_DCP, 417 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 418 - }; 419 - 420 414 static const enum power_supply_property tusb1210_psy_props[] = { 421 415 POWER_SUPPLY_PROP_ONLINE, 422 416 POWER_SUPPLY_PROP_USB_TYPE, ··· 420 426 static const struct power_supply_desc tusb1210_psy_desc = { 421 427 .name = "tusb1211-charger-detect", 422 428 .type = POWER_SUPPLY_TYPE_USB, 423 - .usb_types = tusb1210_psy_usb_types, 424 - .num_usb_types = ARRAY_SIZE(tusb1210_psy_usb_types), 429 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 430 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 431 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 425 432 .properties = tusb1210_psy_props, 426 433 .num_properties = ARRAY_SIZE(tusb1210_psy_props), 427 434 .get_property = tusb1210_psy_get_prop,
+17 -42
drivers/power/reset/brcmstb-reboot.c
··· 18 18 #include <linux/smp.h> 19 19 #include <linux/mfd/syscon.h> 20 20 21 - #define RESET_SOURCE_ENABLE_REG 1 22 - #define SW_MASTER_RESET_REG 2 23 - 24 21 static struct regmap *regmap; 25 22 static u32 rst_src_en; 26 23 static u32 sw_mstr_rst; ··· 29 32 30 33 static const struct reset_reg_mask *reset_masks; 31 34 32 - static int brcmstb_restart_handler(struct notifier_block *this, 33 - unsigned long mode, void *cmd) 35 + static int brcmstb_restart_handler(struct sys_off_data *data) 34 36 { 35 37 int rc; 36 38 u32 tmp; ··· 58 62 return NOTIFY_DONE; 59 63 } 60 64 61 - while (1) 62 - ; 63 - 64 65 return NOTIFY_DONE; 65 66 } 66 - 67 - static struct notifier_block brcmstb_restart_nb = { 68 - .notifier_call = brcmstb_restart_handler, 69 - .priority = 128, 70 - }; 71 67 72 68 static const struct reset_reg_mask reset_bits_40nm = { 73 69 .rst_src_en_mask = BIT(0), ··· 71 83 .sw_mstr_rst_mask = BIT(31), 72 84 }; 73 85 74 - static const struct of_device_id of_match[] = { 75 - { .compatible = "brcm,brcmstb-reboot", .data = &reset_bits_40nm }, 76 - { .compatible = "brcm,bcm7038-reboot", .data = &reset_bits_65nm }, 77 - {}, 78 - }; 79 - 80 86 static int brcmstb_reboot_probe(struct platform_device *pdev) 81 87 { 82 88 int rc; 83 89 struct device_node *np = pdev->dev.of_node; 84 - const struct of_device_id *of_id; 90 + unsigned int args[2]; 85 91 86 - of_id = of_match_node(of_match, np); 87 - if (!of_id) { 88 - pr_err("failed to look up compatible string\n"); 92 + reset_masks = device_get_match_data(&pdev->dev); 93 + if (!reset_masks) { 94 + pr_err("failed to get match data\n"); 89 95 return -EINVAL; 90 96 } 91 - reset_masks = of_id->data; 92 97 93 - regmap = syscon_regmap_lookup_by_phandle(np, "syscon"); 98 + regmap = syscon_regmap_lookup_by_phandle_args(np, "syscon", ARRAY_SIZE(args), args); 94 99 if (IS_ERR(regmap)) { 95 100 pr_err("failed to get syscon phandle\n"); 96 101 return -EINVAL; 97 102 } 103 + rst_src_en = args[0]; 104 + sw_mstr_rst = args[1]; 98 105 99 - rc = of_property_read_u32_index(np, "syscon", RESET_SOURCE_ENABLE_REG, 100 - &rst_src_en); 101 - if (rc) { 102 - pr_err("can't get rst_src_en offset (%d)\n", rc); 103 - return -EINVAL; 104 - } 105 - 106 - rc = of_property_read_u32_index(np, "syscon", SW_MASTER_RESET_REG, 107 - &sw_mstr_rst); 108 - if (rc) { 109 - pr_err("can't get sw_mstr_rst offset (%d)\n", rc); 110 - return -EINVAL; 111 - } 112 - 113 - rc = register_restart_handler(&brcmstb_restart_nb); 106 + rc = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART, 107 + 128, brcmstb_restart_handler, NULL); 114 108 if (rc) 115 109 dev_err(&pdev->dev, 116 110 "cannot register restart handler (err=%d)\n", rc); 117 111 118 112 return rc; 119 113 } 114 + 115 + static const struct of_device_id of_match[] = { 116 + { .compatible = "brcm,brcmstb-reboot", .data = &reset_bits_40nm }, 117 + { .compatible = "brcm,bcm7038-reboot", .data = &reset_bits_65nm }, 118 + {}, 119 + }; 120 120 121 121 static struct platform_driver brcmstb_reboot_driver = { 122 122 .probe = brcmstb_reboot_probe, ··· 116 140 117 141 static int __init brcmstb_reboot_init(void) 118 142 { 119 - return platform_driver_probe(&brcmstb_reboot_driver, 120 - brcmstb_reboot_probe); 143 + return platform_driver_register(&brcmstb_reboot_driver); 121 144 } 122 145 subsys_initcall(brcmstb_reboot_init);
+3 -13
drivers/power/reset/pwr-mlxbf.c
··· 18 18 19 19 struct pwr_mlxbf { 20 20 struct work_struct reboot_work; 21 - struct work_struct shutdown_work; 22 21 const char *hid; 23 22 }; 24 23 ··· 26 27 acpi_bus_generate_netlink_event("button/reboot.*", "Reboot Button", 0x80, 1); 27 28 } 28 29 29 - static void pwr_mlxbf_shutdown_work(struct work_struct *work) 30 - { 31 - acpi_bus_generate_netlink_event("button/power.*", "Power Button", 0x80, 1); 32 - } 33 - 34 30 static irqreturn_t pwr_mlxbf_irq(int irq, void *ptr) 35 31 { 36 32 const char *rst_pwr_hid = "MLNXBF24"; 37 - const char *low_pwr_hid = "MLNXBF29"; 33 + const char *shutdown_hid = "MLNXBF29"; 38 34 struct pwr_mlxbf *priv = ptr; 39 35 40 36 if (!strncmp(priv->hid, rst_pwr_hid, 8)) 41 37 schedule_work(&priv->reboot_work); 42 38 43 - if (!strncmp(priv->hid, low_pwr_hid, 8)) 44 - schedule_work(&priv->shutdown_work); 39 + if (!strncmp(priv->hid, shutdown_hid, 8)) 40 + orderly_poweroff(true); 45 41 46 42 return IRQ_HANDLED; 47 43 } ··· 63 69 irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0); 64 70 if (irq < 0) 65 71 return dev_err_probe(dev, irq, "Error getting %s irq.\n", priv->hid); 66 - 67 - err = devm_work_autocancel(dev, &priv->shutdown_work, pwr_mlxbf_shutdown_work); 68 - if (err) 69 - return err; 70 72 71 73 err = devm_work_autocancel(dev, &priv->reboot_work, pwr_mlxbf_reboot_work); 72 74 if (err)
+1 -1
drivers/power/supply/ab8500_fg.c
··· 2531 2531 }; 2532 2532 ATTRIBUTE_GROUPS(ab8500_fg); 2533 2533 2534 - static struct kobj_type ab8500_fg_ktype = { 2534 + static const struct kobj_type ab8500_fg_ktype = { 2535 2535 .sysfs_ops = &ab8500_fg_sysfs_ops, 2536 2536 .default_groups = ab8500_fg_groups, 2537 2537 };
+534 -57
drivers/power/supply/axp20x_battery.c
··· 17 17 * GNU General Public License for more details. 18 18 */ 19 19 20 + #include <linux/bitfield.h> 20 21 #include <linux/err.h> 21 22 #include <linux/interrupt.h> 22 23 #include <linux/irq.h> ··· 33 32 #include <linux/mfd/axp20x.h> 34 33 35 34 #define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2) 35 + #define AXP717_PWR_STATUS_MASK GENMASK(6, 5) 36 + #define AXP717_PWR_STATUS_BAT_STANDBY 0 37 + #define AXP717_PWR_STATUS_BAT_CHRG 1 38 + #define AXP717_PWR_STATUS_BAT_DISCHRG 2 36 39 37 40 #define AXP20X_PWR_OP_BATT_PRESENT BIT(5) 38 41 #define AXP20X_PWR_OP_BATT_ACTIVATED BIT(3) 42 + #define AXP717_PWR_OP_BATT_PRESENT BIT(3) 43 + 44 + #define AXP717_BATT_PMU_FAULT_MASK GENMASK(2, 0) 45 + #define AXP717_BATT_UVLO_2_5V BIT(2) 46 + #define AXP717_BATT_OVER_TEMP BIT(1) 47 + #define AXP717_BATT_UNDER_TEMP BIT(0) 39 48 40 49 #define AXP209_FG_PERCENT GENMASK(6, 0) 41 50 #define AXP22X_FG_VALID BIT(7) ··· 60 49 #define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5) 61 50 #define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5) 62 51 52 + #define AXP717_CHRG_ENABLE BIT(1) 53 + #define AXP717_CHRG_CV_VOLT_MASK GENMASK(2, 0) 54 + #define AXP717_CHRG_CV_4_0V 0 55 + #define AXP717_CHRG_CV_4_1V 1 56 + #define AXP717_CHRG_CV_4_2V 2 57 + #define AXP717_CHRG_CV_4_35V 3 58 + #define AXP717_CHRG_CV_4_4V 4 59 + /* Values 5 and 6 reserved. */ 60 + #define AXP717_CHRG_CV_5_0V 7 61 + 63 62 #define AXP813_CHRG_CTRL1_TGT_4_35V (3 << 5) 64 63 65 64 #define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0) 65 + #define AXP717_ICC_CHARGER_LIM_MASK GENMASK(5, 0) 66 + 67 + #define AXP717_ITERM_CHG_LIM_MASK GENMASK(3, 0) 68 + #define AXP717_ITERM_CC_STEP 64000 66 69 67 70 #define AXP20X_V_OFF_MASK GENMASK(2, 0) 71 + #define AXP717_V_OFF_MASK GENMASK(6, 4) 72 + 73 + #define AXP717_BAT_VMIN_MIN_UV 2600000 74 + #define AXP717_BAT_VMIN_MAX_UV 3300000 75 + #define AXP717_BAT_VMIN_STEP 100000 76 + #define AXP717_BAT_CV_MIN_UV 4000000 77 + #define AXP717_BAT_CV_MAX_UV 5000000 78 + #define AXP717_BAT_CC_MIN_UA 0 79 + #define AXP717_BAT_CC_MAX_UA 3008000 68 80 69 81 struct axp20x_batt_ps; 70 82 71 83 struct axp_data { 72 - int ccc_scale; 73 - int ccc_offset; 74 - bool has_fg_valid; 84 + int ccc_scale; 85 + int ccc_offset; 86 + unsigned int ccc_reg; 87 + unsigned int ccc_mask; 88 + bool has_fg_valid; 89 + const struct power_supply_desc *bat_ps_desc; 75 90 int (*get_max_voltage)(struct axp20x_batt_ps *batt, int *val); 76 91 int (*set_max_voltage)(struct axp20x_batt_ps *batt, int val); 92 + int (*cfg_iio_chan)(struct platform_device *pdev, 93 + struct axp20x_batt_ps *axp_batt); 94 + void (*set_bat_info)(struct platform_device *pdev, 95 + struct axp20x_batt_ps *axp_batt, 96 + struct power_supply_battery_info *info); 77 97 }; 78 98 79 99 struct axp20x_batt_ps { ··· 177 135 return 0; 178 136 } 179 137 138 + static int axp717_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 139 + int *val) 140 + { 141 + int ret, reg; 142 + 143 + ret = regmap_read(axp20x_batt->regmap, AXP717_CV_CHG_SET, &reg); 144 + if (ret) 145 + return ret; 146 + 147 + switch (reg & AXP717_CHRG_CV_VOLT_MASK) { 148 + case AXP717_CHRG_CV_4_0V: 149 + *val = 4000000; 150 + return 0; 151 + case AXP717_CHRG_CV_4_1V: 152 + *val = 4100000; 153 + return 0; 154 + case AXP717_CHRG_CV_4_2V: 155 + *val = 4200000; 156 + return 0; 157 + case AXP717_CHRG_CV_4_35V: 158 + *val = 4350000; 159 + return 0; 160 + case AXP717_CHRG_CV_4_4V: 161 + *val = 4400000; 162 + return 0; 163 + case AXP717_CHRG_CV_5_0V: 164 + *val = 5000000; 165 + return 0; 166 + default: 167 + return -EINVAL; 168 + } 169 + } 170 + 180 171 static int axp813_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt, 181 172 int *val) 182 173 { ··· 251 176 *val &= AXP20X_CHRG_CTRL1_TGT_CURR; 252 177 253 178 *val = *val * axp->data->ccc_scale + axp->data->ccc_offset; 179 + 180 + return 0; 181 + } 182 + 183 + static int axp717_get_constant_charge_current(struct axp20x_batt_ps *axp, 184 + int *val) 185 + { 186 + int ret; 187 + 188 + ret = regmap_read(axp->regmap, AXP717_ICC_CHG_SET, val); 189 + if (ret) 190 + return ret; 191 + 192 + *val = FIELD_GET(AXP717_ICC_CHARGER_LIM_MASK, *val) * 193 + axp->data->ccc_scale; 254 194 255 195 return 0; 256 196 } ··· 393 303 val->intval = reg & AXP209_FG_PERCENT; 394 304 break; 395 305 396 - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 306 + case POWER_SUPPLY_PROP_VOLTAGE_MAX: 397 307 return axp20x_batt->data->get_max_voltage(axp20x_batt, 398 308 &val->intval); 399 309 400 - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 310 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 401 311 ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, &reg); 402 312 if (ret) 403 313 return ret; ··· 420 330 } 421 331 422 332 return 0; 333 + } 334 + 335 + static int axp717_battery_get_prop(struct power_supply *psy, 336 + enum power_supply_property psp, 337 + union power_supply_propval *val) 338 + { 339 + struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 340 + int ret = 0, reg; 341 + 342 + switch (psp) { 343 + case POWER_SUPPLY_PROP_PRESENT: 344 + case POWER_SUPPLY_PROP_ONLINE: 345 + ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE, 346 + &reg); 347 + if (ret) 348 + return ret; 349 + 350 + val->intval = FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg); 351 + return 0; 352 + 353 + case POWER_SUPPLY_PROP_STATUS: 354 + ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_STATUS_2, 355 + &reg); 356 + if (ret) 357 + return ret; 358 + 359 + switch (FIELD_GET(AXP717_PWR_STATUS_MASK, reg)) { 360 + case AXP717_PWR_STATUS_BAT_STANDBY: 361 + val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; 362 + return 0; 363 + 364 + case AXP717_PWR_STATUS_BAT_CHRG: 365 + val->intval = POWER_SUPPLY_STATUS_CHARGING; 366 + return 0; 367 + 368 + case AXP717_PWR_STATUS_BAT_DISCHRG: 369 + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; 370 + return 0; 371 + 372 + default: 373 + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; 374 + return 0; 375 + } 376 + 377 + /* 378 + * If a fault is detected it must also be cleared; if the 379 + * condition persists it should reappear (This is an 380 + * assumption, it's actually not documented). A restart was 381 + * not sufficient to clear the bit in testing despite the 382 + * register listed as POR. 383 + */ 384 + case POWER_SUPPLY_PROP_HEALTH: 385 + ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_FAULT, 386 + &reg); 387 + if (ret) 388 + return ret; 389 + 390 + switch (reg & AXP717_BATT_PMU_FAULT_MASK) { 391 + case AXP717_BATT_UVLO_2_5V: 392 + val->intval = POWER_SUPPLY_HEALTH_DEAD; 393 + regmap_update_bits(axp20x_batt->regmap, 394 + AXP717_PMU_FAULT, 395 + AXP717_BATT_UVLO_2_5V, 396 + AXP717_BATT_UVLO_2_5V); 397 + return 0; 398 + 399 + case AXP717_BATT_OVER_TEMP: 400 + val->intval = POWER_SUPPLY_HEALTH_HOT; 401 + regmap_update_bits(axp20x_batt->regmap, 402 + AXP717_PMU_FAULT, 403 + AXP717_BATT_OVER_TEMP, 404 + AXP717_BATT_OVER_TEMP); 405 + return 0; 406 + 407 + case AXP717_BATT_UNDER_TEMP: 408 + val->intval = POWER_SUPPLY_HEALTH_COLD; 409 + regmap_update_bits(axp20x_batt->regmap, 410 + AXP717_PMU_FAULT, 411 + AXP717_BATT_UNDER_TEMP, 412 + AXP717_BATT_UNDER_TEMP); 413 + return 0; 414 + 415 + default: 416 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 417 + return 0; 418 + } 419 + 420 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 421 + ret = axp717_get_constant_charge_current(axp20x_batt, 422 + &val->intval); 423 + if (ret) 424 + return ret; 425 + return 0; 426 + 427 + case POWER_SUPPLY_PROP_CURRENT_NOW: 428 + /* 429 + * The offset of this value is currently unknown and is 430 + * not documented in the datasheet. Based on 431 + * observation it's assumed to be somewhere around 432 + * 450ma. I will leave the value raw for now. 433 + */ 434 + ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval); 435 + if (ret) 436 + return ret; 437 + /* IIO framework gives mA but Power Supply framework gives uA */ 438 + val->intval *= 1000; 439 + return 0; 440 + 441 + case POWER_SUPPLY_PROP_CAPACITY: 442 + ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE, 443 + &reg); 444 + if (ret) 445 + return ret; 446 + 447 + if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg)) 448 + return -ENODEV; 449 + 450 + ret = regmap_read(axp20x_batt->regmap, 451 + AXP717_BATT_PERCENT_DATA, &reg); 452 + if (ret) 453 + return ret; 454 + 455 + /* 456 + * Fuel Gauge data takes 7 bits but the stored value seems to be 457 + * directly the raw percentage without any scaling to 7 bits. 458 + */ 459 + val->intval = reg & AXP209_FG_PERCENT; 460 + return 0; 461 + 462 + case POWER_SUPPLY_PROP_VOLTAGE_MAX: 463 + return axp20x_batt->data->get_max_voltage(axp20x_batt, 464 + &val->intval); 465 + 466 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 467 + ret = regmap_read(axp20x_batt->regmap, 468 + AXP717_VSYS_V_POWEROFF, &reg); 469 + if (ret) 470 + return ret; 471 + 472 + val->intval = AXP717_BAT_VMIN_MIN_UV + AXP717_BAT_VMIN_STEP * 473 + (reg & AXP717_V_OFF_MASK); 474 + return 0; 475 + 476 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 477 + ret = iio_read_channel_processed(axp20x_batt->batt_v, 478 + &val->intval); 479 + if (ret) 480 + return ret; 481 + 482 + /* IIO framework gives mV but Power Supply framework gives uV */ 483 + val->intval *= 1000; 484 + return 0; 485 + 486 + case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 487 + ret = regmap_read(axp20x_batt->regmap, 488 + AXP717_ITERM_CHG_SET, &reg); 489 + if (ret) 490 + return ret; 491 + 492 + val->intval = (reg & AXP717_ITERM_CHG_LIM_MASK) * AXP717_ITERM_CC_STEP; 493 + return 0; 494 + 495 + default: 496 + return -EINVAL; 497 + } 423 498 } 424 499 425 500 static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, ··· 643 388 AXP20X_CHRG_CTRL1_TGT_VOLT, val); 644 389 } 645 390 391 + static int axp717_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt, 392 + int val) 393 + { 394 + switch (val) { 395 + case 4000000: 396 + val = AXP717_CHRG_CV_4_0V; 397 + break; 398 + 399 + case 4100000: 400 + val = AXP717_CHRG_CV_4_1V; 401 + break; 402 + 403 + case 4200000: 404 + val = AXP717_CHRG_CV_4_2V; 405 + break; 406 + 407 + default: 408 + /* 409 + * AXP717 can go up to 4.35, 4.4, and 5.0 volts which 410 + * seem too high for lithium batteries, so do not allow. 411 + */ 412 + return -EINVAL; 413 + } 414 + 415 + return regmap_update_bits(axp20x_batt->regmap, 416 + AXP717_CV_CHG_SET, 417 + AXP717_CHRG_CV_VOLT_MASK, val); 418 + } 419 + 646 420 static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt, 647 421 int charge_current) 648 422 { ··· 686 402 687 403 return regmap_update_bits(axp_batt->regmap, AXP20X_CHRG_CTRL1, 688 404 AXP20X_CHRG_CTRL1_TGT_CURR, charge_current); 405 + } 406 + 407 + static int axp717_set_constant_charge_current(struct axp20x_batt_ps *axp, 408 + int charge_current) 409 + { 410 + int val; 411 + 412 + if (charge_current > axp->max_ccc) 413 + return -EINVAL; 414 + 415 + if (charge_current > AXP717_BAT_CC_MAX_UA || charge_current < 0) 416 + return -EINVAL; 417 + 418 + val = (charge_current - axp->data->ccc_offset) / 419 + axp->data->ccc_scale; 420 + 421 + return regmap_update_bits(axp->regmap, AXP717_ICC_CHG_SET, 422 + AXP717_ICC_CHARGER_LIM_MASK, val); 689 423 } 690 424 691 425 static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp, ··· 750 448 AXP20X_V_OFF_MASK, val1); 751 449 } 752 450 451 + static int axp717_set_voltage_min_design(struct axp20x_batt_ps *axp_batt, 452 + int min_voltage) 453 + { 454 + int val1 = (min_voltage - AXP717_BAT_VMIN_MIN_UV) / AXP717_BAT_VMIN_STEP; 455 + 456 + if (val1 < 0 || val1 > AXP717_V_OFF_MASK) 457 + return -EINVAL; 458 + 459 + return regmap_update_bits(axp_batt->regmap, 460 + AXP717_VSYS_V_POWEROFF, 461 + AXP717_V_OFF_MASK, val1); 462 + } 463 + 753 464 static int axp20x_battery_set_prop(struct power_supply *psy, 754 465 enum power_supply_property psp, 755 466 const union power_supply_propval *val) ··· 770 455 struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 771 456 772 457 switch (psp) { 773 - case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN: 458 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 774 459 return axp20x_set_voltage_min_design(axp20x_batt, val->intval); 775 460 776 - case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN: 461 + case POWER_SUPPLY_PROP_VOLTAGE_MAX: 777 462 return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval); 778 463 779 464 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT: ··· 799 484 } 800 485 } 801 486 487 + static int axp717_battery_set_prop(struct power_supply *psy, 488 + enum power_supply_property psp, 489 + const union power_supply_propval *val) 490 + { 491 + struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy); 492 + 493 + switch (psp) { 494 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 495 + return axp717_set_voltage_min_design(axp20x_batt, val->intval); 496 + 497 + case POWER_SUPPLY_PROP_VOLTAGE_MAX: 498 + return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval); 499 + 500 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 501 + return axp717_set_constant_charge_current(axp20x_batt, 502 + val->intval); 503 + case POWER_SUPPLY_PROP_STATUS: 504 + switch (val->intval) { 505 + case POWER_SUPPLY_STATUS_CHARGING: 506 + return regmap_update_bits(axp20x_batt->regmap, 507 + AXP717_MODULE_EN_CONTROL_2, 508 + AXP717_CHRG_ENABLE, 509 + AXP717_CHRG_ENABLE); 510 + 511 + case POWER_SUPPLY_STATUS_DISCHARGING: 512 + case POWER_SUPPLY_STATUS_NOT_CHARGING: 513 + return regmap_update_bits(axp20x_batt->regmap, 514 + AXP717_MODULE_EN_CONTROL_2, 515 + AXP717_CHRG_ENABLE, 0); 516 + } 517 + return -EINVAL; 518 + default: 519 + return -EINVAL; 520 + } 521 + } 522 + 802 523 static enum power_supply_property axp20x_battery_props[] = { 803 524 POWER_SUPPLY_PROP_PRESENT, 804 525 POWER_SUPPLY_PROP_ONLINE, ··· 844 493 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT, 845 494 POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 846 495 POWER_SUPPLY_PROP_HEALTH, 847 - POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 848 - POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 496 + POWER_SUPPLY_PROP_VOLTAGE_MAX, 497 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 849 498 POWER_SUPPLY_PROP_CAPACITY, 499 + }; 500 + 501 + static enum power_supply_property axp717_battery_props[] = { 502 + POWER_SUPPLY_PROP_PRESENT, 503 + POWER_SUPPLY_PROP_ONLINE, 504 + POWER_SUPPLY_PROP_STATUS, 505 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 506 + POWER_SUPPLY_PROP_CURRENT_NOW, 507 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 508 + POWER_SUPPLY_PROP_HEALTH, 509 + POWER_SUPPLY_PROP_VOLTAGE_MAX, 510 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 511 + POWER_SUPPLY_PROP_CAPACITY, 512 + POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT, 850 513 }; 851 514 852 515 static int axp20x_battery_prop_writeable(struct power_supply *psy, 853 516 enum power_supply_property psp) 854 517 { 855 518 return psp == POWER_SUPPLY_PROP_STATUS || 856 - psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN || 857 - psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN || 519 + psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || 520 + psp == POWER_SUPPLY_PROP_VOLTAGE_MAX || 858 521 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT || 859 522 psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; 860 523 } 861 524 862 - static const struct power_supply_desc axp20x_batt_ps_desc = { 525 + static int axp717_battery_prop_writeable(struct power_supply *psy, 526 + enum power_supply_property psp) 527 + { 528 + return psp == POWER_SUPPLY_PROP_STATUS || 529 + psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || 530 + psp == POWER_SUPPLY_PROP_VOLTAGE_MAX || 531 + psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX; 532 + } 533 + 534 + static const struct power_supply_desc axp209_batt_ps_desc = { 863 535 .name = "axp20x-battery", 864 536 .type = POWER_SUPPLY_TYPE_BATTERY, 865 537 .properties = axp20x_battery_props, ··· 892 518 .set_property = axp20x_battery_set_prop, 893 519 }; 894 520 521 + static const struct power_supply_desc axp717_batt_ps_desc = { 522 + .name = "axp20x-battery", 523 + .type = POWER_SUPPLY_TYPE_BATTERY, 524 + .properties = axp717_battery_props, 525 + .num_properties = ARRAY_SIZE(axp717_battery_props), 526 + .property_is_writeable = axp717_battery_prop_writeable, 527 + .get_property = axp717_battery_get_prop, 528 + .set_property = axp717_battery_set_prop, 529 + }; 530 + 531 + static int axp209_bat_cfg_iio_channels(struct platform_device *pdev, 532 + struct axp20x_batt_ps *axp_batt) 533 + { 534 + axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v"); 535 + if (IS_ERR(axp_batt->batt_v)) { 536 + if (PTR_ERR(axp_batt->batt_v) == -ENODEV) 537 + return -EPROBE_DEFER; 538 + return PTR_ERR(axp_batt->batt_v); 539 + } 540 + 541 + axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev, 542 + "batt_chrg_i"); 543 + if (IS_ERR(axp_batt->batt_chrg_i)) { 544 + if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV) 545 + return -EPROBE_DEFER; 546 + return PTR_ERR(axp_batt->batt_chrg_i); 547 + } 548 + 549 + axp_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev, 550 + "batt_dischrg_i"); 551 + if (IS_ERR(axp_batt->batt_dischrg_i)) { 552 + if (PTR_ERR(axp_batt->batt_dischrg_i) == -ENODEV) 553 + return -EPROBE_DEFER; 554 + return PTR_ERR(axp_batt->batt_dischrg_i); 555 + } 556 + 557 + return 0; 558 + } 559 + 560 + static int axp717_bat_cfg_iio_channels(struct platform_device *pdev, 561 + struct axp20x_batt_ps *axp_batt) 562 + { 563 + axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v"); 564 + if (IS_ERR(axp_batt->batt_v)) { 565 + if (PTR_ERR(axp_batt->batt_v) == -ENODEV) 566 + return -EPROBE_DEFER; 567 + return PTR_ERR(axp_batt->batt_v); 568 + } 569 + 570 + axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev, 571 + "batt_chrg_i"); 572 + if (IS_ERR(axp_batt->batt_chrg_i)) { 573 + if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV) 574 + return -EPROBE_DEFER; 575 + return PTR_ERR(axp_batt->batt_chrg_i); 576 + } 577 + 578 + return 0; 579 + } 580 + 581 + static void axp209_set_battery_info(struct platform_device *pdev, 582 + struct axp20x_batt_ps *axp_batt, 583 + struct power_supply_battery_info *info) 584 + { 585 + int vmin = info->voltage_min_design_uv; 586 + int ccc = info->constant_charge_current_max_ua; 587 + 588 + if (vmin > 0 && axp20x_set_voltage_min_design(axp_batt, vmin)) 589 + dev_err(&pdev->dev, 590 + "couldn't set voltage_min_design\n"); 591 + 592 + /* Set max to unverified value to be able to set CCC */ 593 + axp_batt->max_ccc = ccc; 594 + 595 + if (ccc <= 0 || axp20x_set_constant_charge_current(axp_batt, ccc)) { 596 + dev_err(&pdev->dev, 597 + "couldn't set ccc from DT: fallback to min value\n"); 598 + ccc = 300000; 599 + axp_batt->max_ccc = ccc; 600 + axp20x_set_constant_charge_current(axp_batt, ccc); 601 + } 602 + } 603 + 604 + static void axp717_set_battery_info(struct platform_device *pdev, 605 + struct axp20x_batt_ps *axp_batt, 606 + struct power_supply_battery_info *info) 607 + { 608 + int vmin = info->voltage_min_design_uv; 609 + int vmax = info->voltage_max_design_uv; 610 + int ccc = info->constant_charge_current_max_ua; 611 + int val; 612 + 613 + if (vmin > 0 && axp717_set_voltage_min_design(axp_batt, vmin)) 614 + dev_err(&pdev->dev, 615 + "couldn't set voltage_min_design\n"); 616 + 617 + if (vmax > 0 && axp717_battery_set_max_voltage(axp_batt, vmax)) 618 + dev_err(&pdev->dev, 619 + "couldn't set voltage_max_design\n"); 620 + 621 + axp717_get_constant_charge_current(axp_batt, &val); 622 + axp_batt->max_ccc = ccc; 623 + if (ccc <= 0 || axp717_set_constant_charge_current(axp_batt, ccc)) { 624 + dev_err(&pdev->dev, 625 + "couldn't set ccc from DT: current ccc is %d\n", 626 + val); 627 + } 628 + } 629 + 895 630 static const struct axp_data axp209_data = { 896 631 .ccc_scale = 100000, 897 632 .ccc_offset = 300000, 633 + .ccc_reg = AXP20X_CHRG_CTRL1, 634 + .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR, 635 + .bat_ps_desc = &axp209_batt_ps_desc, 898 636 .get_max_voltage = axp20x_battery_get_max_voltage, 899 637 .set_max_voltage = axp20x_battery_set_max_voltage, 638 + .cfg_iio_chan = axp209_bat_cfg_iio_channels, 639 + .set_bat_info = axp209_set_battery_info, 900 640 }; 901 641 902 642 static const struct axp_data axp221_data = { 903 643 .ccc_scale = 150000, 904 644 .ccc_offset = 300000, 645 + .ccc_reg = AXP20X_CHRG_CTRL1, 646 + .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR, 905 647 .has_fg_valid = true, 648 + .bat_ps_desc = &axp209_batt_ps_desc, 906 649 .get_max_voltage = axp22x_battery_get_max_voltage, 907 650 .set_max_voltage = axp22x_battery_set_max_voltage, 651 + .cfg_iio_chan = axp209_bat_cfg_iio_channels, 652 + .set_bat_info = axp209_set_battery_info, 653 + }; 654 + 655 + static const struct axp_data axp717_data = { 656 + .ccc_scale = 64000, 657 + .ccc_offset = 0, 658 + .ccc_reg = AXP717_ICC_CHG_SET, 659 + .ccc_mask = AXP717_ICC_CHARGER_LIM_MASK, 660 + .bat_ps_desc = &axp717_batt_ps_desc, 661 + .get_max_voltage = axp717_battery_get_max_voltage, 662 + .set_max_voltage = axp717_battery_set_max_voltage, 663 + .cfg_iio_chan = axp717_bat_cfg_iio_channels, 664 + .set_bat_info = axp717_set_battery_info, 908 665 }; 909 666 910 667 static const struct axp_data axp813_data = { 911 668 .ccc_scale = 200000, 912 669 .ccc_offset = 200000, 670 + .ccc_reg = AXP20X_CHRG_CTRL1, 671 + .ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR, 913 672 .has_fg_valid = true, 673 + .bat_ps_desc = &axp209_batt_ps_desc, 914 674 .get_max_voltage = axp813_battery_get_max_voltage, 915 675 .set_max_voltage = axp20x_battery_set_max_voltage, 676 + .cfg_iio_chan = axp209_bat_cfg_iio_channels, 677 + .set_bat_info = axp209_set_battery_info, 916 678 }; 917 679 918 680 static const struct of_device_id axp20x_battery_ps_id[] = { ··· 1058 548 }, { 1059 549 .compatible = "x-powers,axp221-battery-power-supply", 1060 550 .data = (void *)&axp221_data, 551 + }, { 552 + .compatible = "x-powers,axp717-battery-power-supply", 553 + .data = (void *)&axp717_data, 1061 554 }, { 1062 555 .compatible = "x-powers,axp813-battery-power-supply", 1063 556 .data = (void *)&axp813_data, ··· 1074 561 struct power_supply_config psy_cfg = {}; 1075 562 struct power_supply_battery_info *info; 1076 563 struct device *dev = &pdev->dev; 564 + int ret; 1077 565 1078 566 if (!of_device_is_available(pdev->dev.of_node)) 1079 567 return -ENODEV; ··· 1086 572 1087 573 axp20x_batt->dev = &pdev->dev; 1088 574 1089 - axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v"); 1090 - if (IS_ERR(axp20x_batt->batt_v)) { 1091 - if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV) 1092 - return -EPROBE_DEFER; 1093 - return PTR_ERR(axp20x_batt->batt_v); 1094 - } 1095 - 1096 - axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev, 1097 - "batt_chrg_i"); 1098 - if (IS_ERR(axp20x_batt->batt_chrg_i)) { 1099 - if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV) 1100 - return -EPROBE_DEFER; 1101 - return PTR_ERR(axp20x_batt->batt_chrg_i); 1102 - } 1103 - 1104 - axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev, 1105 - "batt_dischrg_i"); 1106 - if (IS_ERR(axp20x_batt->batt_dischrg_i)) { 1107 - if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV) 1108 - return -EPROBE_DEFER; 1109 - return PTR_ERR(axp20x_batt->batt_dischrg_i); 1110 - } 1111 - 1112 575 axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL); 1113 576 platform_set_drvdata(pdev, axp20x_batt); 1114 577 ··· 1094 603 1095 604 axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev); 1096 605 606 + ret = axp20x_batt->data->cfg_iio_chan(pdev, axp20x_batt); 607 + if (ret) 608 + return ret; 609 + 1097 610 axp20x_batt->batt = devm_power_supply_register(&pdev->dev, 1098 - &axp20x_batt_ps_desc, 611 + axp20x_batt->data->bat_ps_desc, 1099 612 &psy_cfg); 1100 613 if (IS_ERR(axp20x_batt->batt)) { 1101 614 dev_err(&pdev->dev, "failed to register power supply: %ld\n", ··· 1108 613 } 1109 614 1110 615 if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) { 1111 - int vmin = info->voltage_min_design_uv; 1112 - int ccc = info->constant_charge_current_max_ua; 1113 - 1114 - if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt, 1115 - vmin)) 1116 - dev_err(&pdev->dev, 1117 - "couldn't set voltage_min_design\n"); 1118 - 1119 - /* Set max to unverified value to be able to set CCC */ 1120 - axp20x_batt->max_ccc = ccc; 1121 - 1122 - if (ccc <= 0 || axp20x_set_constant_charge_current(axp20x_batt, 1123 - ccc)) { 1124 - dev_err(&pdev->dev, 1125 - "couldn't set constant charge current from DT: fallback to minimum value\n"); 1126 - ccc = 300000; 1127 - axp20x_batt->max_ccc = ccc; 1128 - axp20x_set_constant_charge_current(axp20x_batt, ccc); 1129 - } 616 + axp20x_batt->data->set_bat_info(pdev, axp20x_batt, info); 617 + power_supply_put_battery_info(axp20x_batt->batt, info); 1130 618 } 1131 619 1132 620 /* 1133 621 * Update max CCC to a valid value if battery info is present or set it 1134 622 * to current register value by default. 1135 623 */ 1136 - axp20x_get_constant_charge_current(axp20x_batt, 1137 - &axp20x_batt->max_ccc); 624 + axp20x_get_constant_charge_current(axp20x_batt, &axp20x_batt->max_ccc); 1138 625 1139 626 return 0; 1140 627 }
+326 -42
drivers/power/supply/axp20x_usb_power.c
··· 30 30 #define AXP20X_PWR_STATUS_VBUS_PRESENT BIT(5) 31 31 #define AXP20X_PWR_STATUS_VBUS_USED BIT(4) 32 32 33 + #define AXP717_PWR_STATUS_VBUS_GOOD BIT(5) 34 + 33 35 #define AXP20X_USB_STATUS_VBUS_VALID BIT(2) 36 + 37 + #define AXP717_PMU_FAULT_VBUS BIT(5) 38 + #define AXP717_PMU_FAULT_VSYS BIT(3) 34 39 35 40 #define AXP20X_VBUS_VHOLD_uV(b) (4000000 + (((b) >> 3) & 7) * 100000) 36 41 #define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3) ··· 44 39 #define AXP20X_ADC_EN1_VBUS_CURR BIT(2) 45 40 #define AXP20X_ADC_EN1_VBUS_VOLT BIT(3) 46 41 42 + #define AXP717_INPUT_VOL_LIMIT_MASK GENMASK(3, 0) 43 + #define AXP717_INPUT_CUR_LIMIT_MASK GENMASK(5, 0) 44 + #define AXP717_ADC_DATA_MASK GENMASK(14, 0) 45 + 46 + #define AXP717_ADC_EN_VBUS_VOLT BIT(2) 47 + 47 48 /* 48 49 * Note do not raise the debounce time, we must report Vusb high within 49 50 * 100ms otherwise we get Vbus errors in musb. 50 51 */ 51 52 #define DEBOUNCE_TIME msecs_to_jiffies(50) 53 + 54 + struct axp20x_usb_power; 52 55 53 56 struct axp_data { 54 57 const struct power_supply_desc *power_desc; ··· 71 58 struct reg_field usb_bc_det_fld; 72 59 struct reg_field vbus_disable_bit; 73 60 bool vbus_needs_polling: 1; 61 + void (*axp20x_read_vbus)(struct work_struct *work); 62 + int (*axp20x_cfg_iio_chan)(struct platform_device *pdev, 63 + struct axp20x_usb_power *power); 64 + int (*axp20x_cfg_adc_reg)(struct axp20x_usb_power *power); 74 65 }; 75 66 76 67 struct axp20x_usb_power { ··· 91 74 struct iio_channel *vbus_v; 92 75 struct iio_channel *vbus_i; 93 76 struct delayed_work vbus_detect; 77 + int max_input_cur; 94 78 unsigned int old_status; 95 79 unsigned int online; 96 80 unsigned int num_irqs; ··· 152 134 out: 153 135 if (axp20x_usb_vbus_needs_polling(power)) 154 136 mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME); 137 + } 138 + 139 + static void axp717_usb_power_poll_vbus(struct work_struct *work) 140 + { 141 + struct axp20x_usb_power *power = 142 + container_of(work, struct axp20x_usb_power, vbus_detect.work); 143 + unsigned int val; 144 + int ret; 145 + 146 + ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &val); 147 + if (ret) 148 + return; 149 + 150 + val &= AXP717_PWR_STATUS_VBUS_GOOD; 151 + if (val != power->old_status) 152 + power_supply_changed(power->supply); 153 + 154 + power->old_status = val; 155 155 } 156 156 157 157 static int axp20x_get_usb_type(struct axp20x_usb_power *power, ··· 317 281 return 0; 318 282 } 319 283 284 + static int axp717_usb_power_get_property(struct power_supply *psy, 285 + enum power_supply_property psp, union power_supply_propval *val) 286 + { 287 + struct axp20x_usb_power *power = power_supply_get_drvdata(psy); 288 + unsigned int v; 289 + int ret; 290 + 291 + switch (psp) { 292 + case POWER_SUPPLY_PROP_HEALTH: 293 + val->intval = POWER_SUPPLY_HEALTH_GOOD; 294 + ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &v); 295 + if (ret) 296 + return ret; 297 + 298 + if (!(v & AXP717_PWR_STATUS_VBUS_GOOD)) 299 + val->intval = POWER_SUPPLY_HEALTH_UNKNOWN; 300 + 301 + ret = regmap_read(power->regmap, AXP717_PMU_FAULT_VBUS, &v); 302 + if (ret) 303 + return ret; 304 + 305 + v &= (AXP717_PMU_FAULT_VBUS | AXP717_PMU_FAULT_VSYS); 306 + if (v) { 307 + val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE; 308 + regmap_write(power->regmap, AXP717_PMU_FAULT_VBUS, v); 309 + } 310 + 311 + break; 312 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 313 + ret = regmap_read(power->regmap, AXP717_INPUT_CUR_LIMIT_CTRL, &v); 314 + if (ret) 315 + return ret; 316 + 317 + /* 50ma step size with 100ma offset. */ 318 + v &= AXP717_INPUT_CUR_LIMIT_MASK; 319 + val->intval = (v * 50000) + 100000; 320 + break; 321 + case POWER_SUPPLY_PROP_ONLINE: 322 + case POWER_SUPPLY_PROP_PRESENT: 323 + ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &v); 324 + if (ret) 325 + return ret; 326 + val->intval = !!(v & AXP717_PWR_STATUS_VBUS_GOOD); 327 + break; 328 + case POWER_SUPPLY_PROP_USB_TYPE: 329 + return axp20x_get_usb_type(power, val); 330 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 331 + ret = regmap_read(power->regmap, AXP717_INPUT_VOL_LIMIT_CTRL, &v); 332 + if (ret) 333 + return ret; 334 + 335 + /* 80mv step size with 3.88v offset. */ 336 + v &= AXP717_INPUT_VOL_LIMIT_MASK; 337 + val->intval = (v * 80000) + 3880000; 338 + break; 339 + case POWER_SUPPLY_PROP_VOLTAGE_NOW: 340 + if (IS_ENABLED(CONFIG_AXP20X_ADC)) { 341 + ret = iio_read_channel_processed(power->vbus_v, 342 + &val->intval); 343 + if (ret) 344 + return ret; 345 + 346 + /* 347 + * IIO framework gives mV but Power Supply framework 348 + * gives uV. 349 + */ 350 + val->intval *= 1000; 351 + return 0; 352 + } 353 + 354 + ret = axp20x_read_variable_width(power->regmap, 355 + AXP717_VBUS_V_H, 16); 356 + if (ret < 0) 357 + return ret; 358 + 359 + val->intval = (ret % AXP717_ADC_DATA_MASK) * 1000; 360 + break; 361 + default: 362 + return -EINVAL; 363 + } 364 + 365 + return 0; 366 + 367 + } 368 + 320 369 static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power, 321 370 int intval) 322 371 { ··· 428 307 return -EINVAL; 429 308 } 430 309 310 + static int axp717_usb_power_set_voltage_min(struct axp20x_usb_power *power, 311 + int intval) 312 + { 313 + int val; 314 + 315 + /* Minimum value of 3.88v and maximum of 5.08v. */ 316 + if (intval < 3880000 || intval > 5080000) 317 + return -EINVAL; 318 + 319 + /* step size of 80ma with 3.88v offset. */ 320 + val = (intval - 3880000) / 80000; 321 + return regmap_update_bits(power->regmap, 322 + AXP717_INPUT_VOL_LIMIT_CTRL, 323 + AXP717_INPUT_VOL_LIMIT_MASK, val); 324 + } 325 + 431 326 static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *power, 432 327 int intval) 433 328 { ··· 453 316 454 317 if (intval == -1) 455 318 return -EINVAL; 319 + 320 + if (power->max_input_cur && (intval > power->max_input_cur)) { 321 + dev_warn(power->dev, 322 + "requested current %d clamped to max current %d\n", 323 + intval, power->max_input_cur); 324 + intval = power->max_input_cur; 325 + } 456 326 457 327 /* 458 328 * BC1.2 detection can cause a race condition if we try to set a current ··· 484 340 return regmap_field_write(power->curr_lim_fld, reg); 485 341 } 486 342 343 + static int axp717_usb_power_set_input_current_limit(struct axp20x_usb_power *power, 344 + int intval) 345 + { 346 + int tmp; 347 + 348 + /* Minimum value of 100mA and maximum value of 3.25A*/ 349 + if (intval < 100000 || intval > 3250000) 350 + return -EINVAL; 351 + 352 + if (power->max_input_cur && (intval > power->max_input_cur)) { 353 + dev_warn(power->dev, 354 + "reqested current %d clamped to max current %d\n", 355 + intval, power->max_input_cur); 356 + intval = power->max_input_cur; 357 + } 358 + 359 + /* Minimum value of 100mA with step size of 50mA. */ 360 + tmp = (intval - 100000) / 50000; 361 + return regmap_update_bits(power->regmap, 362 + AXP717_INPUT_CUR_LIMIT_CTRL, 363 + AXP717_INPUT_CUR_LIMIT_MASK, tmp); 364 + } 365 + 487 366 static int axp20x_usb_power_set_property(struct power_supply *psy, 488 367 enum power_supply_property psp, 489 368 const union power_supply_propval *val) ··· 525 358 526 359 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 527 360 return axp20x_usb_power_set_input_current_limit(power, val->intval); 361 + 362 + default: 363 + return -EINVAL; 364 + } 365 + } 366 + 367 + static int axp717_usb_power_set_property(struct power_supply *psy, 368 + enum power_supply_property psp, 369 + const union power_supply_propval *val) 370 + { 371 + struct axp20x_usb_power *power = power_supply_get_drvdata(psy); 372 + 373 + switch (psp) { 374 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 375 + return axp717_usb_power_set_input_current_limit(power, val->intval); 376 + 377 + case POWER_SUPPLY_PROP_VOLTAGE_MIN: 378 + return axp717_usb_power_set_voltage_min(power, val->intval); 528 379 529 380 default: 530 381 return -EINVAL; ··· 570 385 psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; 571 386 } 572 387 388 + static int axp717_usb_power_prop_writeable(struct power_supply *psy, 389 + enum power_supply_property psp) 390 + { 391 + return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN || 392 + psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT; 393 + } 394 + 395 + static int axp20x_configure_iio_channels(struct platform_device *pdev, 396 + struct axp20x_usb_power *power) 397 + { 398 + power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v"); 399 + if (IS_ERR(power->vbus_v)) { 400 + if (PTR_ERR(power->vbus_v) == -ENODEV) 401 + return -EPROBE_DEFER; 402 + return PTR_ERR(power->vbus_v); 403 + } 404 + 405 + power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i"); 406 + if (IS_ERR(power->vbus_i)) { 407 + if (PTR_ERR(power->vbus_i) == -ENODEV) 408 + return -EPROBE_DEFER; 409 + return PTR_ERR(power->vbus_i); 410 + } 411 + 412 + return 0; 413 + } 414 + 415 + static int axp717_configure_iio_channels(struct platform_device *pdev, 416 + struct axp20x_usb_power *power) 417 + { 418 + power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v"); 419 + if (IS_ERR(power->vbus_v)) { 420 + if (PTR_ERR(power->vbus_v) == -ENODEV) 421 + return -EPROBE_DEFER; 422 + return PTR_ERR(power->vbus_v); 423 + } 424 + 425 + return 0; 426 + } 427 + 428 + static int axp20x_configure_adc_registers(struct axp20x_usb_power *power) 429 + { 430 + /* Enable vbus voltage and current measurement */ 431 + return regmap_update_bits(power->regmap, AXP20X_ADC_EN1, 432 + AXP20X_ADC_EN1_VBUS_CURR | 433 + AXP20X_ADC_EN1_VBUS_VOLT, 434 + AXP20X_ADC_EN1_VBUS_CURR | 435 + AXP20X_ADC_EN1_VBUS_VOLT); 436 + } 437 + 438 + static int axp717_configure_adc_registers(struct axp20x_usb_power *power) 439 + { 440 + /* Enable vbus voltage measurement */ 441 + return regmap_update_bits(power->regmap, AXP717_ADC_CH_EN_CONTROL, 442 + AXP717_ADC_EN_VBUS_VOLT, 443 + AXP717_ADC_EN_VBUS_VOLT); 444 + } 445 + 573 446 static enum power_supply_property axp20x_usb_power_properties[] = { 574 447 POWER_SUPPLY_PROP_HEALTH, 575 448 POWER_SUPPLY_PROP_PRESENT, ··· 646 403 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 647 404 }; 648 405 406 + static enum power_supply_property axp717_usb_power_properties[] = { 407 + POWER_SUPPLY_PROP_HEALTH, 408 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 409 + POWER_SUPPLY_PROP_ONLINE, 410 + POWER_SUPPLY_PROP_PRESENT, 411 + POWER_SUPPLY_PROP_USB_TYPE, 412 + POWER_SUPPLY_PROP_VOLTAGE_MIN, 413 + POWER_SUPPLY_PROP_VOLTAGE_NOW, 414 + }; 415 + 649 416 static enum power_supply_property axp813_usb_power_properties[] = { 650 417 POWER_SUPPLY_PROP_HEALTH, 651 418 POWER_SUPPLY_PROP_PRESENT, ··· 663 410 POWER_SUPPLY_PROP_VOLTAGE_MIN, 664 411 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 665 412 POWER_SUPPLY_PROP_USB_TYPE, 666 - }; 667 - 668 - static enum power_supply_usb_type axp813_usb_types[] = { 669 - POWER_SUPPLY_USB_TYPE_SDP, 670 - POWER_SUPPLY_USB_TYPE_DCP, 671 - POWER_SUPPLY_USB_TYPE_CDP, 672 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 673 413 }; 674 414 675 415 static const struct power_supply_desc axp20x_usb_power_desc = { ··· 685 439 .set_property = axp20x_usb_power_set_property, 686 440 }; 687 441 442 + static const struct power_supply_desc axp717_usb_power_desc = { 443 + .name = "axp20x-usb", 444 + .type = POWER_SUPPLY_TYPE_USB, 445 + .properties = axp717_usb_power_properties, 446 + .num_properties = ARRAY_SIZE(axp717_usb_power_properties), 447 + .property_is_writeable = axp717_usb_power_prop_writeable, 448 + .get_property = axp717_usb_power_get_property, 449 + .set_property = axp717_usb_power_set_property, 450 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 451 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 452 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 453 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 454 + }; 455 + 688 456 static const struct power_supply_desc axp813_usb_power_desc = { 689 457 .name = "axp20x-usb", 690 458 .type = POWER_SUPPLY_TYPE_USB, ··· 707 447 .property_is_writeable = axp20x_usb_power_prop_writeable, 708 448 .get_property = axp20x_usb_power_get_property, 709 449 .set_property = axp20x_usb_power_set_property, 710 - .usb_types = axp813_usb_types, 711 - .num_usb_types = ARRAY_SIZE(axp813_usb_types), 450 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 451 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 452 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 453 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 712 454 }; 713 455 714 456 static const char * const axp20x_irq_names[] = { ··· 723 461 static const char * const axp22x_irq_names[] = { 724 462 "VBUS_PLUGIN", 725 463 "VBUS_REMOVAL", 464 + }; 465 + 466 + static const char * const axp717_irq_names[] = { 467 + "VBUS_PLUGIN", 468 + "VBUS_REMOVAL", 469 + "VBUS_OVER_V", 726 470 }; 727 471 728 472 static int axp192_usb_curr_lim_table[] = { ··· 773 505 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1), 774 506 .vbus_valid_bit = REG_FIELD(AXP192_USB_OTG_STATUS, 2, 2), 775 507 .vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3), 508 + .axp20x_read_vbus = &axp20x_usb_power_poll_vbus, 509 + .axp20x_cfg_iio_chan = axp20x_configure_iio_channels, 510 + .axp20x_cfg_adc_reg = axp20x_configure_adc_registers, 776 511 }; 777 512 778 513 static const struct axp_data axp202_data = { ··· 787 516 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1), 788 517 .vbus_valid_bit = REG_FIELD(AXP20X_USB_OTG_STATUS, 2, 2), 789 518 .vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3), 519 + .axp20x_read_vbus = &axp20x_usb_power_poll_vbus, 520 + .axp20x_cfg_iio_chan = axp20x_configure_iio_channels, 521 + .axp20x_cfg_adc_reg = axp20x_configure_adc_registers, 790 522 }; 791 523 792 524 static const struct axp_data axp221_data = { ··· 800 526 .curr_lim_table_size = ARRAY_SIZE(axp221_usb_curr_lim_table), 801 527 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1), 802 528 .vbus_needs_polling = true, 529 + .axp20x_read_vbus = &axp20x_usb_power_poll_vbus, 530 + .axp20x_cfg_iio_chan = axp20x_configure_iio_channels, 531 + .axp20x_cfg_adc_reg = axp20x_configure_adc_registers, 803 532 }; 804 533 805 534 static const struct axp_data axp223_data = { ··· 813 536 .curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table), 814 537 .curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1), 815 538 .vbus_needs_polling = true, 539 + .axp20x_read_vbus = &axp20x_usb_power_poll_vbus, 540 + .axp20x_cfg_iio_chan = axp20x_configure_iio_channels, 541 + .axp20x_cfg_adc_reg = axp20x_configure_adc_registers, 542 + }; 543 + 544 + static const struct axp_data axp717_data = { 545 + .power_desc = &axp717_usb_power_desc, 546 + .irq_names = axp717_irq_names, 547 + .num_irq_names = ARRAY_SIZE(axp717_irq_names), 548 + .curr_lim_fld = REG_FIELD(AXP717_INPUT_CUR_LIMIT_CTRL, 0, 5), 549 + .usb_bc_en_bit = REG_FIELD(AXP717_MODULE_EN_CONTROL_1, 4, 4), 550 + .usb_bc_det_fld = REG_FIELD(AXP717_BC_DETECT, 5, 7), 551 + .vbus_mon_bit = REG_FIELD(AXP717_ADC_CH_EN_CONTROL, 2, 2), 552 + .vbus_needs_polling = false, 553 + .axp20x_read_vbus = &axp717_usb_power_poll_vbus, 554 + .axp20x_cfg_iio_chan = axp717_configure_iio_channels, 555 + .axp20x_cfg_adc_reg = axp717_configure_adc_registers, 816 556 }; 817 557 818 558 static const struct axp_data axp813_data = { ··· 843 549 .usb_bc_det_fld = REG_FIELD(AXP288_BC_DET_STAT, 5, 7), 844 550 .vbus_disable_bit = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 7, 7), 845 551 .vbus_needs_polling = true, 552 + .axp20x_read_vbus = &axp20x_usb_power_poll_vbus, 553 + .axp20x_cfg_iio_chan = axp20x_configure_iio_channels, 554 + .axp20x_cfg_adc_reg = axp20x_configure_adc_registers, 846 555 }; 847 556 848 557 #ifdef CONFIG_PM_SLEEP ··· 887 590 static SIMPLE_DEV_PM_OPS(axp20x_usb_power_pm_ops, axp20x_usb_power_suspend, 888 591 axp20x_usb_power_resume); 889 592 890 - static int configure_iio_channels(struct platform_device *pdev, 891 - struct axp20x_usb_power *power) 892 - { 893 - power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v"); 894 - if (IS_ERR(power->vbus_v)) { 895 - if (PTR_ERR(power->vbus_v) == -ENODEV) 896 - return -EPROBE_DEFER; 897 - return PTR_ERR(power->vbus_v); 898 - } 899 - 900 - power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i"); 901 - if (IS_ERR(power->vbus_i)) { 902 - if (PTR_ERR(power->vbus_i) == -ENODEV) 903 - return -EPROBE_DEFER; 904 - return PTR_ERR(power->vbus_i); 905 - } 906 - 907 - return 0; 908 - } 909 - 910 - static int configure_adc_registers(struct axp20x_usb_power *power) 911 - { 912 - /* Enable vbus voltage and current measurement */ 913 - return regmap_update_bits(power->regmap, AXP20X_ADC_EN1, 914 - AXP20X_ADC_EN1_VBUS_CURR | 915 - AXP20X_ADC_EN1_VBUS_VOLT, 916 - AXP20X_ADC_EN1_VBUS_CURR | 917 - AXP20X_ADC_EN1_VBUS_VOLT); 918 - } 919 - 920 593 static int axp20x_regmap_field_alloc_optional(struct device *dev, 921 594 struct regmap *regmap, 922 595 struct reg_field fdesc, ··· 905 638 906 639 *fieldp = field; 907 640 return 0; 641 + } 642 + 643 + /* Optionally allow users to specify a maximum charging current. */ 644 + static void axp20x_usb_power_parse_dt(struct device *dev, 645 + struct axp20x_usb_power *power) 646 + { 647 + int ret; 648 + 649 + ret = device_property_read_u32(dev, "input-current-limit-microamp", 650 + &power->max_input_cur); 651 + if (ret) 652 + dev_dbg(dev, "%s() no input-current-limit specified\n", __func__); 908 653 } 909 654 910 655 static int axp20x_usb_power_probe(struct platform_device *pdev) ··· 955 676 if (IS_ERR(power->curr_lim_fld)) 956 677 return PTR_ERR(power->curr_lim_fld); 957 678 679 + axp20x_usb_power_parse_dt(&pdev->dev, power); 680 + 958 681 ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap, 959 682 axp_data->vbus_valid_bit, 960 683 &power->vbus_valid_bit); ··· 988 707 return ret; 989 708 990 709 ret = devm_delayed_work_autocancel(&pdev->dev, &power->vbus_detect, 991 - axp20x_usb_power_poll_vbus); 710 + axp_data->axp20x_read_vbus); 992 711 if (ret) 993 712 return ret; 994 713 ··· 999 718 return ret; 1000 719 1001 720 if (IS_ENABLED(CONFIG_AXP20X_ADC)) 1002 - ret = configure_iio_channels(pdev, power); 721 + ret = axp_data->axp20x_cfg_iio_chan(pdev, power); 1003 722 else 1004 - ret = configure_adc_registers(power); 723 + ret = axp_data->axp20x_cfg_adc_reg(power); 1005 724 1006 725 if (ret) 1007 726 return ret; ··· 1059 778 }, { 1060 779 .compatible = "x-powers,axp223-usb-power-supply", 1061 780 .data = &axp223_data, 781 + }, { 782 + .compatible = "x-powers,axp717-usb-power-supply", 783 + .data = &axp717_data, 1062 784 }, { 1063 785 .compatible = "x-powers,axp813-usb-power-supply", 1064 786 .data = &axp813_data,
+5 -10
drivers/power/supply/bq256xx_charger.c
··· 334 334 1290000, 1360000, 1430000, 1500000 335 335 }; 336 336 337 - static enum power_supply_usb_type bq256xx_usb_type[] = { 338 - POWER_SUPPLY_USB_TYPE_SDP, 339 - POWER_SUPPLY_USB_TYPE_CDP, 340 - POWER_SUPPLY_USB_TYPE_DCP, 341 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 342 - POWER_SUPPLY_USB_TYPE_ACA, 343 - }; 344 - 345 337 static int bq256xx_array_parse(int array_size, int val, const int array[]) 346 338 { 347 339 int i = 0; ··· 1244 1252 static const struct power_supply_desc bq256xx_power_supply_desc = { 1245 1253 .name = "bq256xx-charger", 1246 1254 .type = POWER_SUPPLY_TYPE_USB, 1247 - .usb_types = bq256xx_usb_type, 1248 - .num_usb_types = ARRAY_SIZE(bq256xx_usb_type), 1255 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 1256 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 1257 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 1258 + BIT(POWER_SUPPLY_USB_TYPE_ACA) | 1259 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 1249 1260 .properties = bq256xx_power_supply_props, 1250 1261 .num_properties = ARRAY_SIZE(bq256xx_power_supply_props), 1251 1262 .get_property = bq256xx_get_charger_property,
+1 -1
drivers/power/supply/cpcap-charger.c
··· 904 904 psy_cfg.of_node = pdev->dev.of_node; 905 905 psy_cfg.drv_data = ddata; 906 906 psy_cfg.supplied_to = cpcap_charger_supplied_to; 907 - psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to), 907 + psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to); 908 908 909 909 ddata->usb = devm_power_supply_register(ddata->dev, 910 910 &cpcap_charger_usb_desc,
+8 -14
drivers/power/supply/cros_usbpd-charger.c
··· 73 73 POWER_SUPPLY_PROP_VOLTAGE_NOW, 74 74 }; 75 75 76 - static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = { 77 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 78 - POWER_SUPPLY_USB_TYPE_SDP, 79 - POWER_SUPPLY_USB_TYPE_DCP, 80 - POWER_SUPPLY_USB_TYPE_CDP, 81 - POWER_SUPPLY_USB_TYPE_C, 82 - POWER_SUPPLY_USB_TYPE_PD, 83 - POWER_SUPPLY_USB_TYPE_PD_DRP, 84 - POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID 85 - }; 86 - 87 76 /* Input voltage/current limit in mV/mA. Default to none. */ 88 77 static u16 input_voltage_limit = EC_POWER_LIMIT_NONE; 89 78 static u16 input_current_limit = EC_POWER_LIMIT_NONE; ··· 632 643 psy_desc->properties = cros_usbpd_charger_props; 633 644 psy_desc->num_properties = 634 645 ARRAY_SIZE(cros_usbpd_charger_props); 635 - psy_desc->usb_types = cros_usbpd_charger_usb_types; 636 - psy_desc->num_usb_types = 637 - ARRAY_SIZE(cros_usbpd_charger_usb_types); 646 + psy_desc->usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) | 647 + BIT(POWER_SUPPLY_USB_TYPE_SDP) | 648 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 649 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 650 + BIT(POWER_SUPPLY_USB_TYPE_C) | 651 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 652 + BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) | 653 + BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID); 638 654 } 639 655 640 656 psy_desc->name = port->name;
+1 -6
drivers/power/supply/lenovo_yoga_c630_battery.c
··· 353 353 POWER_SUPPLY_PROP_USB_TYPE, 354 354 }; 355 355 356 - static const enum power_supply_usb_type yoga_c630_psy_adpt_usb_type[] = { 357 - POWER_SUPPLY_USB_TYPE_C, 358 - }; 359 - 360 356 static const struct power_supply_desc yoga_c630_psy_adpt_psy_desc = { 361 357 .name = "yoga-c630-adapter", 362 358 .type = POWER_SUPPLY_TYPE_USB, 363 - .usb_types = yoga_c630_psy_adpt_usb_type, 364 - .num_usb_types = ARRAY_SIZE(yoga_c630_psy_adpt_usb_type), 359 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_C), 365 360 .properties = yoga_c630_psy_adpt_properties, 366 361 .num_properties = ARRAY_SIZE(yoga_c630_psy_adpt_properties), 367 362 .get_property = yoga_c630_psy_adpt_get_property,
+4 -1
drivers/power/supply/max17042_battery.c
··· 853 853 /* program interrupt thresholds such that we should 854 854 * get interrupt for every 'off' perc change in the soc 855 855 */ 856 - regmap_read(map, MAX17042_RepSOC, &soc); 856 + if (chip->pdata->enable_current_sense) 857 + regmap_read(map, MAX17042_RepSOC, &soc); 858 + else 859 + regmap_read(map, MAX17042_VFSOC, &soc); 857 860 soc >>= 8; 858 861 soc_tr = (soc + off) << 8; 859 862 if (off < soc)
+196 -13
drivers/power/supply/max1720x_battery.c
··· 10 10 #include <linux/bitfield.h> 11 11 #include <linux/i2c.h> 12 12 #include <linux/module.h> 13 + #include <linux/nvmem-provider.h> 13 14 #include <linux/power_supply.h> 14 15 #include <linux/regmap.h> 15 16 16 17 #include <asm/unaligned.h> 17 18 18 19 /* Nonvolatile registers */ 20 + #define MAX1720X_NXTABLE0 0x80 19 21 #define MAX1720X_NRSENSE 0xCF /* RSense in 10^-5 Ohm */ 22 + #define MAX1720X_NDEVICE_NAME4 0xDF 20 23 21 24 /* ModelGauge m5 */ 22 25 #define MAX172XX_STATUS 0x00 /* Status */ ··· 49 46 50 47 struct max1720x_device_info { 51 48 struct regmap *regmap; 49 + struct regmap *regmap_nv; 50 + struct i2c_client *ancillary; 52 51 int rsense; 53 52 }; 54 53 ··· 109 104 .rd_table = &max1720x_readable_regs, 110 105 .volatile_table = &max1720x_volatile_regs, 111 106 .cache_type = REGCACHE_RBTREE, 107 + }; 108 + 109 + static const struct regmap_range max1720x_nvmem_allow[] = { 110 + regmap_reg_range(MAX1720X_NXTABLE0, MAX1720X_NDEVICE_NAME4), 111 + }; 112 + 113 + static const struct regmap_range max1720x_nvmem_deny[] = { 114 + regmap_reg_range(0x00, 0x7F), 115 + regmap_reg_range(0xE0, 0xFF), 116 + }; 117 + 118 + static const struct regmap_access_table max1720x_nvmem_regs = { 119 + .yes_ranges = max1720x_nvmem_allow, 120 + .n_yes_ranges = ARRAY_SIZE(max1720x_nvmem_allow), 121 + .no_ranges = max1720x_nvmem_deny, 122 + .n_no_ranges = ARRAY_SIZE(max1720x_nvmem_deny), 123 + }; 124 + 125 + static const struct regmap_config max1720x_nvmem_regmap_cfg = { 126 + .reg_bits = 8, 127 + .val_bits = 16, 128 + .max_register = MAX1720X_NDEVICE_NAME4, 129 + .val_format_endian = REGMAP_ENDIAN_LITTLE, 130 + .rd_table = &max1720x_nvmem_regs, 131 + }; 132 + 133 + static const struct nvmem_cell_info max1720x_nvmem_cells[] = { 134 + { .name = "nXTable0", .offset = 0, .bytes = 2, }, 135 + { .name = "nXTable1", .offset = 2, .bytes = 2, }, 136 + { .name = "nXTable2", .offset = 4, .bytes = 2, }, 137 + { .name = "nXTable3", .offset = 6, .bytes = 2, }, 138 + { .name = "nXTable4", .offset = 8, .bytes = 2, }, 139 + { .name = "nXTable5", .offset = 10, .bytes = 2, }, 140 + { .name = "nXTable6", .offset = 12, .bytes = 2, }, 141 + { .name = "nXTable7", .offset = 14, .bytes = 2, }, 142 + { .name = "nXTable8", .offset = 16, .bytes = 2, }, 143 + { .name = "nXTable9", .offset = 18, .bytes = 2, }, 144 + { .name = "nXTable10", .offset = 20, .bytes = 2, }, 145 + { .name = "nXTable11", .offset = 22, .bytes = 2, }, 146 + { .name = "nUser18C", .offset = 24, .bytes = 2, }, 147 + { .name = "nUser18D", .offset = 26, .bytes = 2, }, 148 + { .name = "nODSCTh", .offset = 28, .bytes = 2, }, 149 + { .name = "nODSCCfg", .offset = 30, .bytes = 2, }, 150 + 151 + { .name = "nOCVTable0", .offset = 32, .bytes = 2, }, 152 + { .name = "nOCVTable1", .offset = 34, .bytes = 2, }, 153 + { .name = "nOCVTable2", .offset = 36, .bytes = 2, }, 154 + { .name = "nOCVTable3", .offset = 38, .bytes = 2, }, 155 + { .name = "nOCVTable4", .offset = 40, .bytes = 2, }, 156 + { .name = "nOCVTable5", .offset = 42, .bytes = 2, }, 157 + { .name = "nOCVTable6", .offset = 44, .bytes = 2, }, 158 + { .name = "nOCVTable7", .offset = 46, .bytes = 2, }, 159 + { .name = "nOCVTable8", .offset = 48, .bytes = 2, }, 160 + { .name = "nOCVTable9", .offset = 50, .bytes = 2, }, 161 + { .name = "nOCVTable10", .offset = 52, .bytes = 2, }, 162 + { .name = "nOCVTable11", .offset = 54, .bytes = 2, }, 163 + { .name = "nIChgTerm", .offset = 56, .bytes = 2, }, 164 + { .name = "nFilterCfg", .offset = 58, .bytes = 2, }, 165 + { .name = "nVEmpty", .offset = 60, .bytes = 2, }, 166 + { .name = "nLearnCfg", .offset = 62, .bytes = 2, }, 167 + 168 + { .name = "nQRTable00", .offset = 64, .bytes = 2, }, 169 + { .name = "nQRTable10", .offset = 66, .bytes = 2, }, 170 + { .name = "nQRTable20", .offset = 68, .bytes = 2, }, 171 + { .name = "nQRTable30", .offset = 70, .bytes = 2, }, 172 + { .name = "nCycles", .offset = 72, .bytes = 2, }, 173 + { .name = "nFullCapNom", .offset = 74, .bytes = 2, }, 174 + { .name = "nRComp0", .offset = 76, .bytes = 2, }, 175 + { .name = "nTempCo", .offset = 78, .bytes = 2, }, 176 + { .name = "nIAvgEmpty", .offset = 80, .bytes = 2, }, 177 + { .name = "nFullCapRep", .offset = 82, .bytes = 2, }, 178 + { .name = "nVoltTemp", .offset = 84, .bytes = 2, }, 179 + { .name = "nMaxMinCurr", .offset = 86, .bytes = 2, }, 180 + { .name = "nMaxMinVolt", .offset = 88, .bytes = 2, }, 181 + { .name = "nMaxMinTemp", .offset = 90, .bytes = 2, }, 182 + { .name = "nSOC", .offset = 92, .bytes = 2, }, 183 + { .name = "nTimerH", .offset = 94, .bytes = 2, }, 184 + 185 + { .name = "nConfig", .offset = 96, .bytes = 2, }, 186 + { .name = "nRippleCfg", .offset = 98, .bytes = 2, }, 187 + { .name = "nMiscCfg", .offset = 100, .bytes = 2, }, 188 + { .name = "nDesignCap", .offset = 102, .bytes = 2, }, 189 + { .name = "nHibCfg", .offset = 104, .bytes = 2, }, 190 + { .name = "nPackCfg", .offset = 106, .bytes = 2, }, 191 + { .name = "nRelaxCfg", .offset = 108, .bytes = 2, }, 192 + { .name = "nConvgCfg", .offset = 110, .bytes = 2, }, 193 + { .name = "nNVCfg0", .offset = 112, .bytes = 2, }, 194 + { .name = "nNVCfg1", .offset = 114, .bytes = 2, }, 195 + { .name = "nNVCfg2", .offset = 116, .bytes = 2, }, 196 + { .name = "nSBSCfg", .offset = 118, .bytes = 2, }, 197 + { .name = "nROMID0", .offset = 120, .bytes = 2, }, 198 + { .name = "nROMID1", .offset = 122, .bytes = 2, }, 199 + { .name = "nROMID2", .offset = 124, .bytes = 2, }, 200 + { .name = "nROMID3", .offset = 126, .bytes = 2, }, 201 + 202 + { .name = "nVAlrtTh", .offset = 128, .bytes = 2, }, 203 + { .name = "nTAlrtTh", .offset = 130, .bytes = 2, }, 204 + { .name = "nSAlrtTh", .offset = 132, .bytes = 2, }, 205 + { .name = "nIAlrtTh", .offset = 134, .bytes = 2, }, 206 + { .name = "nUser1C4", .offset = 136, .bytes = 2, }, 207 + { .name = "nUser1C5", .offset = 138, .bytes = 2, }, 208 + { .name = "nFullSOCThr", .offset = 140, .bytes = 2, }, 209 + { .name = "nTTFCfg", .offset = 142, .bytes = 2, }, 210 + { .name = "nCGain", .offset = 144, .bytes = 2, }, 211 + { .name = "nTCurve", .offset = 146, .bytes = 2, }, 212 + { .name = "nTGain", .offset = 148, .bytes = 2, }, 213 + { .name = "nTOff", .offset = 150, .bytes = 2, }, 214 + { .name = "nManfctrName0", .offset = 152, .bytes = 2, }, 215 + { .name = "nManfctrName1", .offset = 154, .bytes = 2, }, 216 + { .name = "nManfctrName2", .offset = 156, .bytes = 2, }, 217 + { .name = "nRSense", .offset = 158, .bytes = 2, }, 218 + 219 + { .name = "nUser1D0", .offset = 160, .bytes = 2, }, 220 + { .name = "nUser1D1", .offset = 162, .bytes = 2, }, 221 + { .name = "nAgeFcCfg", .offset = 164, .bytes = 2, }, 222 + { .name = "nDesignVoltage", .offset = 166, .bytes = 2, }, 223 + { .name = "nUser1D4", .offset = 168, .bytes = 2, }, 224 + { .name = "nRFastVShdn", .offset = 170, .bytes = 2, }, 225 + { .name = "nManfctrDate", .offset = 172, .bytes = 2, }, 226 + { .name = "nFirstUsed", .offset = 174, .bytes = 2, }, 227 + { .name = "nSerialNumber0", .offset = 176, .bytes = 2, }, 228 + { .name = "nSerialNumber1", .offset = 178, .bytes = 2, }, 229 + { .name = "nSerialNumber2", .offset = 180, .bytes = 2, }, 230 + { .name = "nDeviceName0", .offset = 182, .bytes = 2, }, 231 + { .name = "nDeviceName1", .offset = 184, .bytes = 2, }, 232 + { .name = "nDeviceName2", .offset = 186, .bytes = 2, }, 233 + { .name = "nDeviceName3", .offset = 188, .bytes = 2, }, 234 + { .name = "nDeviceName4", .offset = 190, .bytes = 2, }, 112 235 }; 113 236 114 237 static const enum power_supply_property max1720x_battery_props[] = { ··· 382 249 return ret; 383 250 } 384 251 385 - static int max1720x_probe_sense_resistor(struct i2c_client *client, 386 - struct max1720x_device_info *info) 252 + static 253 + int max1720x_nvmem_reg_read(void *priv, unsigned int off, void *val, size_t len) 254 + { 255 + struct max1720x_device_info *info = priv; 256 + unsigned int reg = MAX1720X_NXTABLE0 + (off / 2); 257 + 258 + return regmap_bulk_read(info->regmap_nv, reg, val, len / 2); 259 + } 260 + 261 + static void max1720x_unregister_ancillary(void *data) 262 + { 263 + struct max1720x_device_info *info = data; 264 + 265 + i2c_unregister_device(info->ancillary); 266 + } 267 + 268 + static int max1720x_probe_nvmem(struct i2c_client *client, 269 + struct max1720x_device_info *info) 387 270 { 388 271 struct device *dev = &client->dev; 389 - struct i2c_client *ancillary; 272 + struct nvmem_config nvmem_config = { 273 + .dev = dev, 274 + .name = "max1720x_nvmem", 275 + .cells = max1720x_nvmem_cells, 276 + .ncells = ARRAY_SIZE(max1720x_nvmem_cells), 277 + .read_only = true, 278 + .root_only = true, 279 + .reg_read = max1720x_nvmem_reg_read, 280 + .size = ARRAY_SIZE(max1720x_nvmem_cells) * 2, 281 + .word_size = 2, 282 + .stride = 2, 283 + .priv = info, 284 + }; 285 + struct nvmem_device *nvmem; 286 + unsigned int val; 390 287 int ret; 391 288 392 - ancillary = i2c_new_ancillary_device(client, "nvmem", 0xb); 393 - if (IS_ERR(ancillary)) { 289 + info->ancillary = i2c_new_ancillary_device(client, "nvmem", 0xb); 290 + if (IS_ERR(info->ancillary)) { 394 291 dev_err(dev, "Failed to initialize ancillary i2c device\n"); 395 - return PTR_ERR(ancillary); 292 + return PTR_ERR(info->ancillary); 396 293 } 397 294 398 - ret = i2c_smbus_read_word_data(ancillary, MAX1720X_NRSENSE); 399 - i2c_unregister_device(ancillary); 400 - if (ret < 0) 295 + ret = devm_add_action_or_reset(dev, max1720x_unregister_ancillary, info); 296 + if (ret) { 297 + dev_err(dev, "Failed to add unregister callback\n"); 401 298 return ret; 299 + } 402 300 403 - info->rsense = ret; 301 + info->regmap_nv = devm_regmap_init_i2c(info->ancillary, 302 + &max1720x_nvmem_regmap_cfg); 303 + if (IS_ERR(info->regmap_nv)) { 304 + dev_err(dev, "regmap initialization of nvmem failed\n"); 305 + return PTR_ERR(info->regmap_nv); 306 + } 307 + 308 + ret = regmap_read(info->regmap_nv, MAX1720X_NRSENSE, &val); 309 + if (ret < 0) { 310 + dev_err(dev, "Failed to read sense resistor value\n"); 311 + return ret; 312 + } 313 + 314 + info->rsense = val; 404 315 if (!info->rsense) { 405 316 dev_warn(dev, "RSense not calibrated, set 10 mOhms!\n"); 406 317 info->rsense = 1000; /* in regs in 10^-5 */ 318 + } 319 + 320 + nvmem = devm_nvmem_register(dev, &nvmem_config); 321 + if (IS_ERR(nvmem)) { 322 + dev_err(dev, "Could not register nvmem!"); 323 + return PTR_ERR(nvmem); 407 324 } 408 325 409 326 return 0; ··· 482 299 483 300 psy_cfg.drv_data = info; 484 301 psy_cfg.fwnode = dev_fwnode(dev); 302 + i2c_set_clientdata(client, info); 485 303 info->regmap = devm_regmap_init_i2c(client, &max1720x_regmap_cfg); 486 304 if (IS_ERR(info->regmap)) 487 305 return dev_err_probe(dev, PTR_ERR(info->regmap), 488 306 "regmap initialization failed\n"); 489 307 490 - ret = max1720x_probe_sense_resistor(client, info); 308 + ret = max1720x_probe_nvmem(client, info); 491 309 if (ret) 492 - return dev_err_probe(dev, ret, 493 - "Failed to read sense resistor value\n"); 310 + return dev_err_probe(dev, ret, "Failed to probe nvmem\n"); 494 311 495 312 bat = devm_power_supply_register(dev, &max1720x_bat_desc, &psy_cfg); 496 313 if (IS_ERR(bat))
+52
drivers/power/supply/max77693_charger.c
··· 197 197 return 0; 198 198 } 199 199 200 + /* 201 + * There are *two* current limit registers: 202 + * - CHGIN limit, which limits the input current from the external charger; 203 + * - Fast charge current limit, which limits the current going to the battery. 204 + */ 205 + 206 + static int max77693_get_input_current_limit(struct regmap *regmap, int *val) 207 + { 208 + unsigned int data; 209 + int ret; 210 + 211 + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_09, &data); 212 + if (ret < 0) 213 + return ret; 214 + 215 + data &= CHG_CNFG_09_CHGIN_ILIM_MASK; 216 + data >>= CHG_CNFG_09_CHGIN_ILIM_SHIFT; 217 + 218 + if (data <= 0x03) 219 + /* The first four values (0x00..0x03) are 60mA */ 220 + *val = 60000; 221 + else 222 + *val = data * 20000; /* 20mA steps */ 223 + 224 + return 0; 225 + } 226 + 227 + static int max77693_get_fast_charge_current(struct regmap *regmap, int *val) 228 + { 229 + unsigned int data; 230 + int ret; 231 + 232 + ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_02, &data); 233 + if (ret < 0) 234 + return ret; 235 + 236 + data &= CHG_CNFG_02_CC_MASK; 237 + data >>= CHG_CNFG_02_CC_SHIFT; 238 + 239 + *val = data * 33300; /* 33.3mA steps */ 240 + 241 + return 0; 242 + } 243 + 200 244 static enum power_supply_property max77693_charger_props[] = { 201 245 POWER_SUPPLY_PROP_STATUS, 202 246 POWER_SUPPLY_PROP_CHARGE_TYPE, 203 247 POWER_SUPPLY_PROP_HEALTH, 204 248 POWER_SUPPLY_PROP_PRESENT, 205 249 POWER_SUPPLY_PROP_ONLINE, 250 + POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, 251 + POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 206 252 POWER_SUPPLY_PROP_MODEL_NAME, 207 253 POWER_SUPPLY_PROP_MANUFACTURER, 208 254 }; ··· 276 230 break; 277 231 case POWER_SUPPLY_PROP_ONLINE: 278 232 ret = max77693_get_online(regmap, &val->intval); 233 + break; 234 + case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT: 235 + ret = max77693_get_input_current_limit(regmap, &val->intval); 236 + break; 237 + case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX: 238 + ret = max77693_get_fast_charge_current(regmap, &val->intval); 279 239 break; 280 240 case POWER_SUPPLY_PROP_MODEL_NAME: 281 241 val->strval = max77693_charger_model;
+1
drivers/power/supply/max8998_charger.c
··· 191 191 { "max8998-battery", TYPE_MAX8998 }, 192 192 { } 193 193 }; 194 + MODULE_DEVICE_TABLE(platform, max8998_battery_id); 194 195 195 196 static struct platform_driver max8998_battery_driver = { 196 197 .driver = {
+5 -10
drivers/power/supply/mp2629_charger.c
··· 94 94 int shift; 95 95 }; 96 96 97 - static enum power_supply_usb_type mp2629_usb_types[] = { 98 - POWER_SUPPLY_USB_TYPE_SDP, 99 - POWER_SUPPLY_USB_TYPE_DCP, 100 - POWER_SUPPLY_USB_TYPE_CDP, 101 - POWER_SUPPLY_USB_TYPE_PD_DRP, 102 - POWER_SUPPLY_USB_TYPE_UNKNOWN 103 - }; 104 - 105 97 static enum power_supply_property mp2629_charger_usb_props[] = { 106 98 POWER_SUPPLY_PROP_ONLINE, 107 99 POWER_SUPPLY_PROP_USB_TYPE, ··· 479 487 static const struct power_supply_desc mp2629_usb_desc = { 480 488 .name = "mp2629_usb", 481 489 .type = POWER_SUPPLY_TYPE_USB, 482 - .usb_types = mp2629_usb_types, 483 - .num_usb_types = ARRAY_SIZE(mp2629_usb_types), 490 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 491 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 492 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 493 + BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) | 494 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 484 495 .properties = mp2629_charger_usb_props, 485 496 .num_properties = ARRAY_SIZE(mp2629_charger_usb_props), 486 497 .get_property = mp2629_charger_usb_get_prop,
+4 -9
drivers/power/supply/mt6360_charger.c
··· 154 154 MT6360_CHG_TYPE_MAX, 155 155 }; 156 156 157 - static enum power_supply_usb_type mt6360_charger_usb_types[] = { 158 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 159 - POWER_SUPPLY_USB_TYPE_SDP, 160 - POWER_SUPPLY_USB_TYPE_DCP, 161 - POWER_SUPPLY_USB_TYPE_CDP, 162 - }; 163 - 164 157 static int mt6360_get_chrdet_ext_stat(struct mt6360_chg_info *mci, 165 158 bool *pwr_rdy) 166 159 { ··· 567 574 .get_property = mt6360_charger_get_property, 568 575 .set_property = mt6360_charger_set_property, 569 576 .property_is_writeable = mt6360_charger_property_is_writeable, 570 - .usb_types = mt6360_charger_usb_types, 571 - .num_usb_types = ARRAY_SIZE(mt6360_charger_usb_types), 577 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 578 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 579 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 580 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 572 581 }; 573 582 574 583 static const struct regulator_ops mt6360_chg_otg_ops = {
+4 -9
drivers/power/supply/mt6370-charger.c
··· 624 624 POWER_SUPPLY_PROP_USB_TYPE, 625 625 }; 626 626 627 - static enum power_supply_usb_type mt6370_chg_usb_types[] = { 628 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 629 - POWER_SUPPLY_USB_TYPE_SDP, 630 - POWER_SUPPLY_USB_TYPE_CDP, 631 - POWER_SUPPLY_USB_TYPE_DCP, 632 - }; 633 - 634 627 static const struct power_supply_desc mt6370_chg_psy_desc = { 635 628 .name = "mt6370-charger", 636 629 .type = POWER_SUPPLY_TYPE_USB, ··· 632 639 .get_property = mt6370_chg_get_property, 633 640 .set_property = mt6370_chg_set_property, 634 641 .property_is_writeable = mt6370_chg_property_is_writeable, 635 - .usb_types = mt6370_chg_usb_types, 636 - .num_usb_types = ARRAY_SIZE(mt6370_chg_usb_types), 642 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 643 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 644 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 645 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 637 646 }; 638 647 639 648 static const struct regulator_ops mt6370_chg_otg_ops = {
+5 -14
drivers/power/supply/power_supply_core.c
··· 9 9 * Modified: 2004, Oct Szabolcs Gyurko 10 10 */ 11 11 12 + #include <linux/cleanup.h> 12 13 #include <linux/module.h> 13 14 #include <linux/types.h> 14 15 #include <linux/init.h> ··· 757 756 758 757 for (index = 0; index < len; index++) { 759 758 struct power_supply_battery_ocv_table *table; 760 - char *propname; 761 759 int i, tab_len, size; 762 760 763 - propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index); 761 + char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", 762 + index); 764 763 if (!propname) { 765 764 power_supply_put_battery_info(psy, info); 766 765 err = -ENOMEM; ··· 769 768 list = of_get_property(battery_np, propname, &size); 770 769 if (!list || !size) { 771 770 dev_err(&psy->dev, "failed to get %s\n", propname); 772 - kfree(propname); 773 771 power_supply_put_battery_info(psy, info); 774 772 err = -EINVAL; 775 773 goto out_put_node; 776 774 } 777 775 778 - kfree(propname); 779 776 tab_len = size / (2 * sizeof(__be32)); 780 777 info->ocv_table_size[index] = tab_len; 781 778 ··· 1231 1232 int power_supply_property_is_writeable(struct power_supply *psy, 1232 1233 enum power_supply_property psp) 1233 1234 { 1234 - if (atomic_read(&psy->use_cnt) <= 0 || 1235 - !psy->desc->property_is_writeable) 1236 - return -ENODEV; 1237 - 1238 - return psy->desc->property_is_writeable(psy, psp); 1235 + return psy->desc->property_is_writeable && psy->desc->property_is_writeable(psy, psp); 1239 1236 } 1240 1237 EXPORT_SYMBOL_GPL(power_supply_property_is_writeable); 1241 1238 ··· 1291 1296 return ret; 1292 1297 } 1293 1298 1294 - static struct thermal_zone_device_ops psy_tzd_ops = { 1299 + static const struct thermal_zone_device_ops psy_tzd_ops = { 1295 1300 .get_temp = power_supply_read_temp, 1296 1301 }; 1297 1302 ··· 1355 1360 if (!parent) 1356 1361 pr_warn("%s: Expected proper parent device for '%s'\n", 1357 1362 __func__, desc->name); 1358 - 1359 - if (psy_has_property(desc, POWER_SUPPLY_PROP_USB_TYPE) && 1360 - (!desc->usb_types || !desc->num_usb_types)) 1361 - return ERR_PTR(-EINVAL); 1362 1363 1363 1364 psy = kzalloc(sizeof(*psy), GFP_KERNEL); 1364 1365 if (!psy)
+2 -1
drivers/power/supply/power_supply_hwmon.c
··· 318 318 HWMON_T_INPUT | 319 319 HWMON_T_MAX | 320 320 HWMON_T_MIN | 321 - HWMON_T_MIN_ALARM, 321 + HWMON_T_MIN_ALARM | 322 + HWMON_T_MAX_ALARM, 322 323 323 324 HWMON_T_LABEL | 324 325 HWMON_T_INPUT |
+21 -45
drivers/power/supply/power_supply_sysfs.c
··· 209 209 POWER_SUPPLY_ATTR(TIME_TO_FULL_NOW), 210 210 POWER_SUPPLY_ATTR(TIME_TO_FULL_AVG), 211 211 POWER_SUPPLY_ENUM_ATTR(TYPE), 212 - POWER_SUPPLY_ATTR(USB_TYPE), 212 + POWER_SUPPLY_ENUM_ATTR(USB_TYPE), 213 213 POWER_SUPPLY_ENUM_ATTR(SCOPE), 214 214 POWER_SUPPLY_ATTR(PRECHARGE_CURRENT), 215 215 POWER_SUPPLY_ATTR(CHARGE_TERM_CURRENT), ··· 237 237 return to_ps_attr(attr) - power_supply_attrs; 238 238 } 239 239 240 - static ssize_t power_supply_show_usb_type(struct device *dev, 241 - const struct power_supply_desc *desc, 242 - union power_supply_propval *value, 243 - char *buf) 240 + static ssize_t power_supply_show_enum_with_available( 241 + struct device *dev, const char * const labels[], int label_count, 242 + unsigned int available_values, int value, char *buf) 244 243 { 245 - enum power_supply_usb_type usb_type; 244 + bool match = false, available, active; 246 245 ssize_t count = 0; 247 - bool match = false; 248 246 int i; 249 247 250 - for (i = 0; i < desc->num_usb_types; ++i) { 251 - usb_type = desc->usb_types[i]; 248 + for (i = 0; i < label_count; i++) { 249 + available = available_values & BIT(i); 250 + active = i == value; 252 251 253 - if (value->intval == usb_type) { 254 - count += sysfs_emit_at(buf, count, "[%s] ", 255 - POWER_SUPPLY_USB_TYPE_TEXT[usb_type]); 252 + if (available && active) { 253 + count += sysfs_emit_at(buf, count, "[%s] ", labels[i]); 256 254 match = true; 257 - } else { 258 - count += sysfs_emit_at(buf, count, "%s ", 259 - POWER_SUPPLY_USB_TYPE_TEXT[usb_type]); 255 + } else if (available) { 256 + count += sysfs_emit_at(buf, count, "%s ", labels[i]); 260 257 } 261 258 } 262 259 263 260 if (!match) { 264 - dev_warn(dev, "driver reporting unsupported connected type\n"); 261 + dev_warn(dev, "driver reporting unavailable enum value %d\n", value); 265 262 return -EINVAL; 266 263 } 267 264 ··· 297 300 298 301 switch (psp) { 299 302 case POWER_SUPPLY_PROP_USB_TYPE: 300 - ret = power_supply_show_usb_type(dev, psy->desc, 301 - &value, buf); 303 + ret = power_supply_show_enum_with_available( 304 + dev, POWER_SUPPLY_USB_TYPE_TEXT, 305 + ARRAY_SIZE(POWER_SUPPLY_USB_TYPE_TEXT), 306 + psy->desc->usb_types, value.intval, buf); 302 307 break; 303 308 case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR: 304 309 ret = power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours, ··· 522 523 enum power_supply_charge_behaviour current_behaviour, 523 524 char *buf) 524 525 { 525 - bool match = false, available, active; 526 - ssize_t count = 0; 527 - int i; 528 - 529 - for (i = 0; i < ARRAY_SIZE(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT); i++) { 530 - available = available_behaviours & BIT(i); 531 - active = i == current_behaviour; 532 - 533 - if (available && active) { 534 - count += sysfs_emit_at(buf, count, "[%s] ", 535 - POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]); 536 - match = true; 537 - } else if (available) { 538 - count += sysfs_emit_at(buf, count, "%s ", 539 - POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]); 540 - } 541 - } 542 - 543 - if (!match) { 544 - dev_warn(dev, "driver reporting unsupported charge behaviour\n"); 545 - return -EINVAL; 546 - } 547 - 548 - if (count) 549 - buf[count - 1] = '\n'; 550 - 551 - return count; 526 + return power_supply_show_enum_with_available( 527 + dev, POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT, 528 + ARRAY_SIZE(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT), 529 + available_behaviours, current_behaviour, buf); 552 530 } 553 531 EXPORT_SYMBOL_GPL(power_supply_charge_behaviour_show); 554 532
+20 -17
drivers/power/supply/qcom_battmgr.c
··· 786 786 return 0; 787 787 } 788 788 789 - static const enum power_supply_usb_type usb_psy_supported_types[] = { 790 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 791 - POWER_SUPPLY_USB_TYPE_SDP, 792 - POWER_SUPPLY_USB_TYPE_DCP, 793 - POWER_SUPPLY_USB_TYPE_CDP, 794 - POWER_SUPPLY_USB_TYPE_ACA, 795 - POWER_SUPPLY_USB_TYPE_C, 796 - POWER_SUPPLY_USB_TYPE_PD, 797 - POWER_SUPPLY_USB_TYPE_PD_DRP, 798 - POWER_SUPPLY_USB_TYPE_PD_PPS, 799 - POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID, 800 - }; 801 - 802 789 static const enum power_supply_property sc8280xp_usb_props[] = { 803 790 POWER_SUPPLY_PROP_ONLINE, 804 791 }; ··· 796 809 .properties = sc8280xp_usb_props, 797 810 .num_properties = ARRAY_SIZE(sc8280xp_usb_props), 798 811 .get_property = qcom_battmgr_usb_get_property, 799 - .usb_types = usb_psy_supported_types, 800 - .num_usb_types = ARRAY_SIZE(usb_psy_supported_types), 812 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) | 813 + BIT(POWER_SUPPLY_USB_TYPE_SDP) | 814 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 815 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 816 + BIT(POWER_SUPPLY_USB_TYPE_ACA) | 817 + BIT(POWER_SUPPLY_USB_TYPE_C) | 818 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 819 + BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) | 820 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) | 821 + BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID), 801 822 }; 802 823 803 824 static const enum power_supply_property sm8350_usb_props[] = { ··· 824 829 .properties = sm8350_usb_props, 825 830 .num_properties = ARRAY_SIZE(sm8350_usb_props), 826 831 .get_property = qcom_battmgr_usb_get_property, 827 - .usb_types = usb_psy_supported_types, 828 - .num_usb_types = ARRAY_SIZE(usb_psy_supported_types), 832 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) | 833 + BIT(POWER_SUPPLY_USB_TYPE_SDP) | 834 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 835 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 836 + BIT(POWER_SUPPLY_USB_TYPE_ACA) | 837 + BIT(POWER_SUPPLY_USB_TYPE_C) | 838 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 839 + BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) | 840 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) | 841 + BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID), 829 842 }; 830 843 831 844 static const u8 sm8350_wls_prop_map[] = {
+4 -9
drivers/power/supply/qcom_pmi8998_charger.c
··· 411 411 POWER_SUPPLY_PROP_USB_TYPE, 412 412 }; 413 413 414 - static enum power_supply_usb_type smb2_usb_types[] = { 415 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 416 - POWER_SUPPLY_USB_TYPE_SDP, 417 - POWER_SUPPLY_USB_TYPE_DCP, 418 - POWER_SUPPLY_USB_TYPE_CDP, 419 - }; 420 - 421 414 static int smb2_get_prop_usb_online(struct smb2_chip *chip, int *val) 422 415 { 423 416 unsigned int stat; ··· 768 775 static const struct power_supply_desc smb2_psy_desc = { 769 776 .name = "pmi8998_charger", 770 777 .type = POWER_SUPPLY_TYPE_USB, 771 - .usb_types = smb2_usb_types, 772 - .num_usb_types = ARRAY_SIZE(smb2_usb_types), 778 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 779 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 780 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 781 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 773 782 .properties = smb2_properties, 774 783 .num_properties = ARRAY_SIZE(smb2_properties), 775 784 .get_property = smb2_get_property,
+2 -7
drivers/power/supply/rk817_charger.c
··· 673 673 POWER_SUPPLY_PROP_VOLTAGE_AVG, 674 674 }; 675 675 676 - static enum power_supply_usb_type rk817_usb_type[] = { 677 - POWER_SUPPLY_USB_TYPE_DCP, 678 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 679 - }; 680 - 681 676 static const struct power_supply_desc rk817_bat_desc = { 682 677 .name = "rk817-battery", 683 678 .type = POWER_SUPPLY_TYPE_BATTERY, ··· 684 689 static const struct power_supply_desc rk817_chg_desc = { 685 690 .name = "rk817-charger", 686 691 .type = POWER_SUPPLY_TYPE_USB, 687 - .usb_types = rk817_usb_type, 688 - .num_usb_types = ARRAY_SIZE(rk817_usb_type), 692 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_DCP) | 693 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 689 694 .properties = rk817_chg_props, 690 695 .num_properties = ARRAY_SIZE(rk817_chg_props), 691 696 .get_property = rk817_chg_get_prop,
+4 -9
drivers/power/supply/rn5t618_power.c
··· 70 70 int irq; 71 71 }; 72 72 73 - static enum power_supply_usb_type rn5t618_usb_types[] = { 74 - POWER_SUPPLY_USB_TYPE_SDP, 75 - POWER_SUPPLY_USB_TYPE_DCP, 76 - POWER_SUPPLY_USB_TYPE_CDP, 77 - POWER_SUPPLY_USB_TYPE_UNKNOWN 78 - }; 79 - 80 73 static enum power_supply_property rn5t618_usb_props[] = { 81 74 /* input current limit is not very accurate */ 82 75 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT, ··· 674 681 static const struct power_supply_desc rn5t618_usb_desc = { 675 682 .name = "rn5t618-usb", 676 683 .type = POWER_SUPPLY_TYPE_USB, 677 - .usb_types = rn5t618_usb_types, 678 - .num_usb_types = ARRAY_SIZE(rn5t618_usb_types), 684 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 685 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 686 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 687 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 679 688 .properties = rn5t618_usb_props, 680 689 .num_properties = ARRAY_SIZE(rn5t618_usb_props), 681 690 .get_property = rn5t618_usb_get_property,
+4 -12
drivers/power/supply/rt9467-charger.c
··· 630 630 return ret; 631 631 } 632 632 633 - static const enum power_supply_usb_type rt9467_chg_usb_types[] = { 634 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 635 - POWER_SUPPLY_USB_TYPE_SDP, 636 - POWER_SUPPLY_USB_TYPE_DCP, 637 - POWER_SUPPLY_USB_TYPE_CDP, 638 - }; 639 - 640 633 static const enum power_supply_property rt9467_chg_properties[] = { 641 634 POWER_SUPPLY_PROP_STATUS, 642 635 POWER_SUPPLY_PROP_ONLINE, ··· 738 745 RT9467_RANGE_IPREC, val->intval); 739 746 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 740 747 return rt9467_psy_set_ieoc(data, val->intval); 741 - case POWER_SUPPLY_PROP_USB_TYPE: 742 - return regmap_field_write(data->rm_field[F_USBCHGEN], val->intval); 743 748 default: 744 749 return -EINVAL; 745 750 } ··· 755 764 case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT: 756 765 case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT: 757 766 case POWER_SUPPLY_PROP_PRECHARGE_CURRENT: 758 - case POWER_SUPPLY_PROP_USB_TYPE: 759 767 return 1; 760 768 default: 761 769 return 0; ··· 764 774 static const struct power_supply_desc rt9467_chg_psy_desc = { 765 775 .name = "rt9467-charger", 766 776 .type = POWER_SUPPLY_TYPE_USB, 767 - .usb_types = rt9467_chg_usb_types, 768 - .num_usb_types = ARRAY_SIZE(rt9467_chg_usb_types), 777 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 778 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 779 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 780 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 769 781 .properties = rt9467_chg_properties, 770 782 .num_properties = ARRAY_SIZE(rt9467_chg_properties), 771 783 .property_is_writeable = rt9467_chg_prop_is_writeable,
+5 -10
drivers/power/supply/rt9471.c
··· 333 333 POWER_SUPPLY_PROP_MANUFACTURER, 334 334 }; 335 335 336 - static enum power_supply_usb_type rt9471_charger_usb_types[] = { 337 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 338 - POWER_SUPPLY_USB_TYPE_SDP, 339 - POWER_SUPPLY_USB_TYPE_DCP, 340 - POWER_SUPPLY_USB_TYPE_CDP, 341 - POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID, 342 - }; 343 - 344 336 static int rt9471_charger_property_is_writeable(struct power_supply *psy, 345 337 enum power_supply_property psp) 346 338 { ··· 718 726 719 727 desc->name = psy_name; 720 728 desc->type = POWER_SUPPLY_TYPE_USB; 721 - desc->usb_types = rt9471_charger_usb_types; 722 - desc->num_usb_types = ARRAY_SIZE(rt9471_charger_usb_types); 729 + desc->usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 730 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 731 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 732 + BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID) | 733 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN); 723 734 desc->properties = rt9471_charger_properties; 724 735 desc->num_properties = ARRAY_SIZE(rt9471_charger_properties); 725 736 desc->get_property = rt9471_charger_get_property;
+1 -1
drivers/power/supply/twl4030_charger.c
··· 363 363 if (status < 0) 364 364 return status; 365 365 cur_reg |= oldreg << 8; 366 - if (reg != oldreg) { 366 + if (reg != cur_reg) { 367 367 /* disable write protection for one write access for 368 368 * BCIIREF */ 369 369 status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7,
+12 -14
drivers/power/supply/ucs1002_power.c
··· 296 296 return 0; 297 297 } 298 298 299 - static enum power_supply_usb_type ucs1002_usb_types[] = { 300 - POWER_SUPPLY_USB_TYPE_PD, 301 - POWER_SUPPLY_USB_TYPE_SDP, 302 - POWER_SUPPLY_USB_TYPE_DCP, 303 - POWER_SUPPLY_USB_TYPE_CDP, 304 - POWER_SUPPLY_USB_TYPE_UNKNOWN, 305 - }; 306 - 307 299 static int ucs1002_set_usb_type(struct ucs1002_info *info, int val) 308 300 { 309 301 unsigned int mode; 310 302 311 - if (val < 0 || val >= ARRAY_SIZE(ucs1002_usb_types)) 312 - return -EINVAL; 313 - 314 - switch (ucs1002_usb_types[val]) { 303 + switch (val) { 304 + /* 305 + * POWER_SUPPLY_USB_TYPE_UNKNOWN == 0, map this to dedicated for 306 + * userspace API compatibility with older versions of this driver 307 + * which mapped 0 to dedicated. 308 + */ 309 + case POWER_SUPPLY_USB_TYPE_UNKNOWN: 315 310 case POWER_SUPPLY_USB_TYPE_PD: 316 311 mode = V_SET_ACTIVE_MODE_DEDICATED; 317 312 break; ··· 423 428 static const struct power_supply_desc ucs1002_charger_desc = { 424 429 .name = "ucs1002", 425 430 .type = POWER_SUPPLY_TYPE_USB, 426 - .usb_types = ucs1002_usb_types, 427 - .num_usb_types = ARRAY_SIZE(ucs1002_usb_types), 431 + .usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) | 432 + BIT(POWER_SUPPLY_USB_TYPE_CDP) | 433 + BIT(POWER_SUPPLY_USB_TYPE_DCP) | 434 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 435 + BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN), 428 436 .get_property = ucs1002_get_property, 429 437 .set_property = ucs1002_set_property, 430 438 .property_is_writeable = ucs1002_property_is_writeable,
+3 -8
drivers/usb/typec/anx7411.c
··· 1339 1339 dev_err(dev, "failed to get GPIO IRQ\n"); 1340 1340 } 1341 1341 1342 - static enum power_supply_usb_type anx7411_psy_usb_types[] = { 1343 - POWER_SUPPLY_USB_TYPE_C, 1344 - POWER_SUPPLY_USB_TYPE_PD, 1345 - POWER_SUPPLY_USB_TYPE_PD_PPS, 1346 - }; 1347 - 1348 1342 static enum power_supply_property anx7411_psy_props[] = { 1349 1343 POWER_SUPPLY_PROP_USB_TYPE, 1350 1344 POWER_SUPPLY_PROP_ONLINE, ··· 1416 1422 1417 1423 psy_desc->name = psy_name; 1418 1424 psy_desc->type = POWER_SUPPLY_TYPE_USB; 1419 - psy_desc->usb_types = anx7411_psy_usb_types; 1420 - psy_desc->num_usb_types = ARRAY_SIZE(anx7411_psy_usb_types); 1425 + psy_desc->usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 1426 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 1427 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS); 1421 1428 psy_desc->properties = anx7411_psy_props; 1422 1429 psy_desc->num_properties = ARRAY_SIZE(anx7411_psy_props); 1423 1430
+3 -8
drivers/usb/typec/rt1719.c
··· 109 109 u16 conn_stat; 110 110 }; 111 111 112 - static const enum power_supply_usb_type rt1719_psy_usb_types[] = { 113 - POWER_SUPPLY_USB_TYPE_C, 114 - POWER_SUPPLY_USB_TYPE_PD, 115 - POWER_SUPPLY_USB_TYPE_PD_PPS 116 - }; 117 - 118 112 static const enum power_supply_property rt1719_psy_properties[] = { 119 113 POWER_SUPPLY_PROP_ONLINE, 120 114 POWER_SUPPLY_PROP_USB_TYPE, ··· 566 572 567 573 data->psy_desc.name = psy_name; 568 574 data->psy_desc.type = POWER_SUPPLY_TYPE_USB; 569 - data->psy_desc.usb_types = rt1719_psy_usb_types; 570 - data->psy_desc.num_usb_types = ARRAY_SIZE(rt1719_psy_usb_types); 575 + data->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 576 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 577 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS); 571 578 data->psy_desc.properties = rt1719_psy_properties; 572 579 data->psy_desc.num_properties = ARRAY_SIZE(rt1719_psy_properties); 573 580 data->psy_desc.get_property = rt1719_psy_get_property;
+3 -8
drivers/usb/typec/tcpm/tcpm.c
··· 7483 7483 } 7484 7484 } 7485 7485 7486 - static enum power_supply_usb_type tcpm_psy_usb_types[] = { 7487 - POWER_SUPPLY_USB_TYPE_C, 7488 - POWER_SUPPLY_USB_TYPE_PD, 7489 - POWER_SUPPLY_USB_TYPE_PD_PPS, 7490 - }; 7491 - 7492 7486 static const char *tcpm_psy_name_prefix = "tcpm-source-psy-"; 7493 7487 7494 7488 static int devm_tcpm_psy_register(struct tcpm_port *port) ··· 7503 7509 port_dev_name); 7504 7510 port->psy_desc.name = psy_name; 7505 7511 port->psy_desc.type = POWER_SUPPLY_TYPE_USB; 7506 - port->psy_desc.usb_types = tcpm_psy_usb_types; 7507 - port->psy_desc.num_usb_types = ARRAY_SIZE(tcpm_psy_usb_types); 7512 + port->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 7513 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 7514 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS); 7508 7515 port->psy_desc.properties = tcpm_psy_props; 7509 7516 port->psy_desc.num_properties = ARRAY_SIZE(tcpm_psy_props); 7510 7517 port->psy_desc.get_property = tcpm_psy_get_prop;
+2 -7
drivers/usb/typec/tipd/core.c
··· 150 150 POWER_SUPPLY_PROP_ONLINE, 151 151 }; 152 152 153 - static enum power_supply_usb_type tps6598x_psy_usb_types[] = { 154 - POWER_SUPPLY_USB_TYPE_C, 155 - POWER_SUPPLY_USB_TYPE_PD, 156 - }; 157 - 158 153 static const char *tps6598x_psy_name_prefix = "tps6598x-source-psy-"; 159 154 160 155 /* ··· 822 827 823 828 tps->psy_desc.name = psy_name; 824 829 tps->psy_desc.type = POWER_SUPPLY_TYPE_USB; 825 - tps->psy_desc.usb_types = tps6598x_psy_usb_types; 826 - tps->psy_desc.num_usb_types = ARRAY_SIZE(tps6598x_psy_usb_types); 830 + tps->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 831 + BIT(POWER_SUPPLY_USB_TYPE_PD); 827 832 tps->psy_desc.properties = tps6598x_psy_props; 828 833 tps->psy_desc.num_properties = ARRAY_SIZE(tps6598x_psy_props); 829 834 tps->psy_desc.get_property = tps6598x_psy_get_prop;
+3 -8
drivers/usb/typec/ucsi/psy.c
··· 254 254 } 255 255 } 256 256 257 - static enum power_supply_usb_type ucsi_psy_usb_types[] = { 258 - POWER_SUPPLY_USB_TYPE_C, 259 - POWER_SUPPLY_USB_TYPE_PD, 260 - POWER_SUPPLY_USB_TYPE_PD_PPS, 261 - }; 262 - 263 257 int ucsi_register_port_psy(struct ucsi_connector *con) 264 258 { 265 259 struct power_supply_config psy_cfg = {}; ··· 270 276 271 277 con->psy_desc.name = psy_name; 272 278 con->psy_desc.type = POWER_SUPPLY_TYPE_USB; 273 - con->psy_desc.usb_types = ucsi_psy_usb_types; 274 - con->psy_desc.num_usb_types = ARRAY_SIZE(ucsi_psy_usb_types); 279 + con->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) | 280 + BIT(POWER_SUPPLY_USB_TYPE_PD) | 281 + BIT(POWER_SUPPLY_USB_TYPE_PD_PPS); 275 282 con->psy_desc.properties = ucsi_psy_props; 276 283 con->psy_desc.num_properties = ARRAY_SIZE(ucsi_psy_props); 277 284 con->psy_desc.get_property = ucsi_psy_get_prop;
+24
include/linux/mfd/axp20x.h
··· 115 115 #define AXP313A_IRQ_STATE 0x21 116 116 117 117 #define AXP717_ON_INDICATE 0x00 118 + #define AXP717_PMU_STATUS_2 0x01 119 + #define AXP717_BC_DETECT 0x05 120 + #define AXP717_PMU_FAULT 0x08 121 + #define AXP717_MODULE_EN_CONTROL_1 0x0b 122 + #define AXP717_MIN_SYS_V_CONTROL 0x15 123 + #define AXP717_INPUT_VOL_LIMIT_CTRL 0x16 124 + #define AXP717_INPUT_CUR_LIMIT_CTRL 0x17 118 125 #define AXP717_MODULE_EN_CONTROL_2 0x19 119 126 #define AXP717_BOOST_CONTROL 0x1e 127 + #define AXP717_VSYS_V_POWEROFF 0x24 120 128 #define AXP717_IRQ0_EN 0x40 121 129 #define AXP717_IRQ1_EN 0x41 122 130 #define AXP717_IRQ2_EN 0x42 ··· 135 127 #define AXP717_IRQ2_STATE 0x4a 136 128 #define AXP717_IRQ3_STATE 0x4b 137 129 #define AXP717_IRQ4_STATE 0x4c 130 + #define AXP717_ICC_CHG_SET 0x62 131 + #define AXP717_ITERM_CHG_SET 0x63 132 + #define AXP717_CV_CHG_SET 0x64 138 133 #define AXP717_DCDC_OUTPUT_CONTROL 0x80 139 134 #define AXP717_DCDC1_CONTROL 0x83 140 135 #define AXP717_DCDC2_CONTROL 0x84 ··· 158 147 #define AXP717_CLDO3_CONTROL 0x9d 159 148 #define AXP717_CLDO4_CONTROL 0x9e 160 149 #define AXP717_CPUSLDO_CONTROL 0x9f 150 + #define AXP717_BATT_PERCENT_DATA 0xa4 151 + #define AXP717_ADC_CH_EN_CONTROL 0xc0 152 + #define AXP717_BATT_V_H 0xc4 153 + #define AXP717_BATT_V_L 0xc5 154 + #define AXP717_VBUS_V_H 0xc6 155 + #define AXP717_VBUS_V_L 0xc7 156 + #define AXP717_VSYS_V_H 0xc8 157 + #define AXP717_VSYS_V_L 0xc9 158 + #define AXP717_BATT_CHRG_I_H 0xca 159 + #define AXP717_BATT_CHRG_I_L 0xcb 160 + #define AXP717_ADC_DATA_SEL 0xcd 161 + #define AXP717_ADC_DATA_H 0xce 162 + #define AXP717_ADC_DATA_L 0xcf 161 163 162 164 #define AXP806_STARTUP_SRC 0x00 163 165 #define AXP806_CHIP_ID 0x03
+5
include/linux/mfd/max77693-private.h
··· 217 217 #define CHG_CNFG_01_CHGRSTRT_MASK (0x3 << CHG_CNFG_01_CHGRSTRT_SHIFT) 218 218 #define CHG_CNFG_01_PQEN_MAKS BIT(CHG_CNFG_01_PQEN_SHIFT) 219 219 220 + /* MAX77693_CHG_REG_CHG_CNFG_02 register */ 221 + #define CHG_CNFG_02_CC_SHIFT 0 222 + #define CHG_CNFG_02_CC_MASK 0x3F 223 + 220 224 /* MAX77693_CHG_REG_CHG_CNFG_03 register */ 221 225 #define CHG_CNFG_03_TOITH_SHIFT 0 222 226 #define CHG_CNFG_03_TOTIME_SHIFT 3 ··· 248 244 #define CHG_CNFG_12_VCHGINREG_MASK (0x3 << CHG_CNFG_12_VCHGINREG_SHIFT) 249 245 250 246 /* MAX77693 CHG_CNFG_09 Register */ 247 + #define CHG_CNFG_09_CHGIN_ILIM_SHIFT 0 251 248 #define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F 252 249 253 250 /* MAX77693 CHG_CTRL Register */
+1 -2
include/linux/power_supply.h
··· 243 243 const char *name; 244 244 enum power_supply_type type; 245 245 u8 charge_behaviours; 246 - const enum power_supply_usb_type *usb_types; 247 - size_t num_usb_types; 246 + u32 usb_types; 248 247 const enum power_supply_property *properties; 249 248 size_t num_properties; 250 249