mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 06:01:57 +00:00
power supply and reset changes for the 6.12 series
* 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEE72YNB0Y/i3JqeVQT2O7X88g7+poFAmbnQh8ACgkQ2O7X88g7 +ppf8g//Ve5sY8zIZs+xSbKEpxOd2NYE5dINj+D5k5wTxPtxzvTscTU3gsl6hpen ws2Z2k1M+6wqt3EkHgE++bov3ZFFixzzzBaJogvdFhNUBi5cSpuu3EOTFbarrMB/ cFlp2jD87TXFhTkWihxn01DTWqxYgoVKQvpbG86D/QWlj1zNAwvGGuAarU7cRPAV 6qkHpV1Q9ZCstdURlYf9tf9NVnw/DVUGwCFAfBEFx45tfyLhlzZU94c+xlNzuLKv UUvhL4SgWly2Q5ica9ad8YJkaW1LQPaM1RlG9mGiPFI6IF8ra41sYawg98Oer/T/ uuSK0N/+jfuaEbwcrNAZqQg+ZCAAIBtpFL3+DpLr0ksGGNmqxGfUhDQ2/IkL7z3b Rhzzzt1xoSPJPZyFscjZ7vPmd9dXd5/Bn017mmlXvj1iCtjRLbacvbDLdrzFYDev k8GVIpzYJbVdJkSZB4spq6nR2VrHc4Vqsx4Nfz0QwFPfvoCaioNkwvdPhmpjN/UL N8m+/ShnUJ09/2NZJ/XBjRlg+UuZD46uZOR0+dObTaOcwYx843tdNRvfmM0RMVH6 5WEjOxPGUMSF/nyvbG1nXiicuKjGgf6/aRukDSYkVnt+mZ9gz2ETa+ZGr58MUQh+ nRzOVJFDmOTyqoXKcSrFQJu7pOiscxxckIDY1IayyxtHbxVlzJE= =UKRL -----END PGP SIGNATURE----- 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() ...
This commit is contained in:
commit
288cb34ead
@ -377,17 +377,33 @@ What: /sys/class/power_supply/<supply_name>/charge_type
|
||||
Date: July 2009
|
||||
Contact: linux-pm@vger.kernel.org
|
||||
Description:
|
||||
Represents the type of charging currently being applied to the
|
||||
battery. "Trickle", "Fast", and "Standard" all mean different
|
||||
charging speeds. "Adaptive" means that the charger uses some
|
||||
algorithm to adjust the charge rate dynamically, without
|
||||
any user configuration required. "Custom" means that the charger
|
||||
uses the charge_control_* properties as configuration for some
|
||||
different algorithm. "Long Life" means the charger reduces its
|
||||
charging rate in order to prolong the battery health. "Bypass"
|
||||
means the charger bypasses the charging path around the
|
||||
integrated converter allowing for a "smart" wall adaptor to
|
||||
perform the power conversion externally.
|
||||
Select the charging algorithm to use for a battery.
|
||||
|
||||
Standard:
|
||||
Fully charge the battery at a moderate rate.
|
||||
Fast:
|
||||
Quickly charge the battery using fast-charge
|
||||
technology. This is typically harder on the battery
|
||||
than standard charging and may lower its lifespan.
|
||||
Trickle:
|
||||
Users who primarily operate the system while
|
||||
plugged into an external power source can extend
|
||||
battery life with this mode. Vendor tooling may
|
||||
call this "Primarily AC Use".
|
||||
Adaptive:
|
||||
Automatically optimize battery charge rate based
|
||||
on typical usage pattern.
|
||||
Custom:
|
||||
Use the charge_control_* properties to determine
|
||||
when to start and stop charging. Advanced users
|
||||
can use this to drastically extend battery life.
|
||||
Long Life:
|
||||
The charger reduces its charging rate in order to
|
||||
prolong the battery health.
|
||||
Bypass:
|
||||
The charger bypasses the charging path around the
|
||||
integrated converter allowing for a "smart" wall
|
||||
adaptor to perform the power conversion externally.
|
||||
|
||||
Access: Read, Write
|
||||
|
||||
@ -592,7 +608,12 @@ Description:
|
||||
the supply, for example it can show if USB-PD capable source
|
||||
is attached.
|
||||
|
||||
Access: Read-Only
|
||||
Access: For power-supplies which consume USB power such
|
||||
as battery charger chips, this indicates the type of
|
||||
the connected USB power source and is Read-Only.
|
||||
|
||||
For power-supplies which act as a USB power-source such as
|
||||
e.g. the UCS1002 USB Port Power Controller this is writable.
|
||||
|
||||
Valid values:
|
||||
"Unknown", "SDP", "DCP", "CDP", "ACA", "C", "PD",
|
||||
|
@ -27,6 +27,9 @@ properties:
|
||||
battery-detect-gpios:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
maxItems: 1
|
||||
|
||||
io-channels:
|
||||
items:
|
||||
- description: Battery Temperature ADC
|
||||
@ -53,6 +56,7 @@ required:
|
||||
- compatible
|
||||
- reg
|
||||
- battery-detect-gpios
|
||||
- interrupts
|
||||
- io-channels
|
||||
- io-channel-names
|
||||
- nvmem-cells
|
||||
@ -88,6 +92,8 @@ examples:
|
||||
compatible = "sprd,sc2731-fgu";
|
||||
reg = <0xa00>;
|
||||
battery-detect-gpios = <&pmic_eic 9 GPIO_ACTIVE_HIGH>;
|
||||
interrupt-parent = <&sc2731_pmic>;
|
||||
interrupts = <4>;
|
||||
io-channels = <&pmic_adc 5>, <&pmic_adc 14>;
|
||||
io-channel-names = "bat-temp", "charge-vol";
|
||||
nvmem-cells = <&fgu_calib>;
|
||||
|
@ -23,11 +23,18 @@ properties:
|
||||
- const: x-powers,axp202-battery-power-supply
|
||||
- const: x-powers,axp209-battery-power-supply
|
||||
- const: x-powers,axp221-battery-power-supply
|
||||
- const: x-powers,axp717-battery-power-supply
|
||||
- items:
|
||||
- const: x-powers,axp803-battery-power-supply
|
||||
- const: x-powers,axp813-battery-power-supply
|
||||
- const: x-powers,axp813-battery-power-supply
|
||||
|
||||
monitored-battery:
|
||||
description:
|
||||
Specifies the phandle of an optional simple-battery connected to
|
||||
this gauge.
|
||||
$ref: /schemas/types.yaml#/definitions/phandle
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
|
@ -15,9 +15,6 @@ maintainers:
|
||||
- Chen-Yu Tsai <wens@csie.org>
|
||||
- Sebastian Reichel <sre@kernel.org>
|
||||
|
||||
allOf:
|
||||
- $ref: power-supply.yaml#
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
@ -26,13 +23,82 @@ properties:
|
||||
- x-powers,axp202-usb-power-supply
|
||||
- x-powers,axp221-usb-power-supply
|
||||
- x-powers,axp223-usb-power-supply
|
||||
- x-powers,axp717-usb-power-supply
|
||||
- x-powers,axp813-usb-power-supply
|
||||
- items:
|
||||
- const: x-powers,axp803-usb-power-supply
|
||||
- const: x-powers,axp813-usb-power-supply
|
||||
|
||||
input-current-limit-microamp:
|
||||
description:
|
||||
Optional value to clamp the maximum input current limit to for
|
||||
the device. If omitted, the programmed value from the EFUSE will
|
||||
be used.
|
||||
minimum: 100000
|
||||
maximum: 4000000
|
||||
|
||||
required:
|
||||
- compatible
|
||||
|
||||
allOf:
|
||||
- $ref: power-supply.yaml#
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- x-powers,axp192-usb-power-supply
|
||||
then:
|
||||
properties:
|
||||
input-current-limit-microamp:
|
||||
enum: [100000, 500000]
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- x-powers,axp202-usb-power-supply
|
||||
- x-powers,axp223-usb-power-supply
|
||||
then:
|
||||
properties:
|
||||
input-current-limit-microamp:
|
||||
enum: [100000, 500000, 900000]
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- x-powers,axp221-usb-power-supply
|
||||
then:
|
||||
properties:
|
||||
input-current-limit-microamp:
|
||||
enum: [500000, 900000]
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- x-powers,axp717-usb-power-supply
|
||||
then:
|
||||
properties:
|
||||
input-current-limit-microamp:
|
||||
description: Maximum input current in increments of 50000 uA.
|
||||
minimum: 100000
|
||||
maximum: 3250000
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
enum:
|
||||
- x-powers,axp813-usb-power-supply
|
||||
then:
|
||||
properties:
|
||||
input-current-limit-microamp:
|
||||
enum: [100000, 500000, 900000, 1500000, 2000000, 2500000,
|
||||
3000000, 3500000, 4000000]
|
||||
|
||||
additionalProperties: false
|
||||
|
@ -461,14 +461,6 @@ static int cht_wc_extcon_psy_get_prop(struct power_supply *psy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const enum power_supply_usb_type cht_wc_extcon_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_ACA,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
static const enum power_supply_property cht_wc_extcon_psy_props[] = {
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
@ -477,8 +469,11 @@ static const enum power_supply_property cht_wc_extcon_psy_props[] = {
|
||||
static const struct power_supply_desc cht_wc_extcon_psy_desc = {
|
||||
.name = "cht_wcove_pwrsrc",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = cht_wc_extcon_psy_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(cht_wc_extcon_psy_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_ACA) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = cht_wc_extcon_psy_props,
|
||||
.num_properties = ARRAY_SIZE(cht_wc_extcon_psy_props),
|
||||
.get_property = cht_wc_extcon_psy_get_prop,
|
||||
|
@ -209,15 +209,23 @@ static const struct regmap_access_table axp313a_volatile_table = {
|
||||
};
|
||||
|
||||
static const struct regmap_range axp717_writeable_ranges[] = {
|
||||
regmap_reg_range(AXP717_MODULE_EN_CONTROL_2, AXP717_MODULE_EN_CONTROL_2),
|
||||
regmap_reg_range(AXP717_BOOST_CONTROL, AXP717_BOOST_CONTROL),
|
||||
regmap_reg_range(AXP717_PMU_FAULT, AXP717_MODULE_EN_CONTROL_1),
|
||||
regmap_reg_range(AXP717_MIN_SYS_V_CONTROL, AXP717_BOOST_CONTROL),
|
||||
regmap_reg_range(AXP717_VSYS_V_POWEROFF, AXP717_VSYS_V_POWEROFF),
|
||||
regmap_reg_range(AXP717_IRQ0_EN, AXP717_IRQ4_EN),
|
||||
regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE),
|
||||
regmap_reg_range(AXP717_ICC_CHG_SET, AXP717_CV_CHG_SET),
|
||||
regmap_reg_range(AXP717_DCDC_OUTPUT_CONTROL, AXP717_CPUSLDO_CONTROL),
|
||||
regmap_reg_range(AXP717_ADC_CH_EN_CONTROL, AXP717_ADC_CH_EN_CONTROL),
|
||||
regmap_reg_range(AXP717_ADC_DATA_SEL, AXP717_ADC_DATA_SEL),
|
||||
};
|
||||
|
||||
static const struct regmap_range axp717_volatile_ranges[] = {
|
||||
regmap_reg_range(AXP717_ON_INDICATE, AXP717_PMU_FAULT),
|
||||
regmap_reg_range(AXP717_IRQ0_STATE, AXP717_IRQ4_STATE),
|
||||
regmap_reg_range(AXP717_BATT_PERCENT_DATA, AXP717_BATT_PERCENT_DATA),
|
||||
regmap_reg_range(AXP717_BATT_V_H, AXP717_BATT_CHRG_I_L),
|
||||
regmap_reg_range(AXP717_ADC_DATA_H, AXP717_ADC_DATA_L),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table axp717_writeable_table = {
|
||||
@ -310,6 +318,12 @@ static const struct resource axp22x_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP22X_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
|
||||
};
|
||||
|
||||
static const struct resource axp717_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_OVER_V, "VBUS_OVER_V"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
|
||||
DEFINE_RES_IRQ_NAMED(AXP717_IRQ_VBUS_REMOVAL, "VBUS_REMOVAL"),
|
||||
};
|
||||
|
||||
/* AXP803 and AXP813/AXP818 share the same interrupts */
|
||||
static const struct resource axp803_usb_power_supply_resources[] = {
|
||||
DEFINE_RES_IRQ_NAMED(AXP803_IRQ_VBUS_PLUGIN, "VBUS_PLUGIN"),
|
||||
@ -424,7 +438,7 @@ static const struct regmap_config axp717_regmap_config = {
|
||||
.val_bits = 8,
|
||||
.wr_table = &axp717_writeable_table,
|
||||
.volatile_table = &axp717_volatile_table,
|
||||
.max_register = AXP717_CPUSLDO_CONTROL,
|
||||
.max_register = AXP717_ADC_DATA_L,
|
||||
.cache_type = REGCACHE_MAPLE,
|
||||
};
|
||||
|
||||
@ -1026,6 +1040,13 @@ static struct mfd_cell axp313a_cells[] = {
|
||||
static struct mfd_cell axp717_cells[] = {
|
||||
MFD_CELL_NAME("axp20x-regulator"),
|
||||
MFD_CELL_RES("axp20x-pek", axp717_pek_resources),
|
||||
MFD_CELL_OF("axp717-adc",
|
||||
NULL, NULL, 0, 0, "x-powers,axp717-adc"),
|
||||
MFD_CELL_OF("axp20x-usb-power-supply",
|
||||
axp717_usb_power_supply_resources, NULL, 0, 0,
|
||||
"x-powers,axp717-usb-power-supply"),
|
||||
MFD_CELL_OF("axp20x-battery-power-supply",
|
||||
NULL, NULL, 0, 0, "x-powers,axp717-battery-power-supply"),
|
||||
};
|
||||
|
||||
static const struct resource axp288_adc_resources[] = {
|
||||
|
@ -411,12 +411,6 @@ static int tusb1210_psy_get_prop(struct power_supply *psy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const enum power_supply_usb_type tusb1210_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
static const enum power_supply_property tusb1210_psy_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
@ -426,8 +420,9 @@ static const enum power_supply_property tusb1210_psy_props[] = {
|
||||
static const struct power_supply_desc tusb1210_psy_desc = {
|
||||
.name = "tusb1211-charger-detect",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = tusb1210_psy_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(tusb1210_psy_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = tusb1210_psy_props,
|
||||
.num_properties = ARRAY_SIZE(tusb1210_psy_props),
|
||||
.get_property = tusb1210_psy_get_prop,
|
||||
|
@ -18,9 +18,6 @@
|
||||
#include <linux/smp.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
|
||||
#define RESET_SOURCE_ENABLE_REG 1
|
||||
#define SW_MASTER_RESET_REG 2
|
||||
|
||||
static struct regmap *regmap;
|
||||
static u32 rst_src_en;
|
||||
static u32 sw_mstr_rst;
|
||||
@ -32,8 +29,7 @@ struct reset_reg_mask {
|
||||
|
||||
static const struct reset_reg_mask *reset_masks;
|
||||
|
||||
static int brcmstb_restart_handler(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
static int brcmstb_restart_handler(struct sys_off_data *data)
|
||||
{
|
||||
int rc;
|
||||
u32 tmp;
|
||||
@ -62,17 +58,9 @@ static int brcmstb_restart_handler(struct notifier_block *this,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
while (1)
|
||||
;
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static struct notifier_block brcmstb_restart_nb = {
|
||||
.notifier_call = brcmstb_restart_handler,
|
||||
.priority = 128,
|
||||
};
|
||||
|
||||
static const struct reset_reg_mask reset_bits_40nm = {
|
||||
.rst_src_en_mask = BIT(0),
|
||||
.sw_mstr_rst_mask = BIT(0),
|
||||
@ -83,46 +71,28 @@ static const struct reset_reg_mask reset_bits_65nm = {
|
||||
.sw_mstr_rst_mask = BIT(31),
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match[] = {
|
||||
{ .compatible = "brcm,brcmstb-reboot", .data = &reset_bits_40nm },
|
||||
{ .compatible = "brcm,bcm7038-reboot", .data = &reset_bits_65nm },
|
||||
{},
|
||||
};
|
||||
|
||||
static int brcmstb_reboot_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
const struct of_device_id *of_id;
|
||||
unsigned int args[2];
|
||||
|
||||
of_id = of_match_node(of_match, np);
|
||||
if (!of_id) {
|
||||
pr_err("failed to look up compatible string\n");
|
||||
reset_masks = device_get_match_data(&pdev->dev);
|
||||
if (!reset_masks) {
|
||||
pr_err("failed to get match data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
reset_masks = of_id->data;
|
||||
|
||||
regmap = syscon_regmap_lookup_by_phandle(np, "syscon");
|
||||
regmap = syscon_regmap_lookup_by_phandle_args(np, "syscon", ARRAY_SIZE(args), args);
|
||||
if (IS_ERR(regmap)) {
|
||||
pr_err("failed to get syscon phandle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
rst_src_en = args[0];
|
||||
sw_mstr_rst = args[1];
|
||||
|
||||
rc = of_property_read_u32_index(np, "syscon", RESET_SOURCE_ENABLE_REG,
|
||||
&rst_src_en);
|
||||
if (rc) {
|
||||
pr_err("can't get rst_src_en offset (%d)\n", rc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_index(np, "syscon", SW_MASTER_RESET_REG,
|
||||
&sw_mstr_rst);
|
||||
if (rc) {
|
||||
pr_err("can't get sw_mstr_rst offset (%d)\n", rc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = register_restart_handler(&brcmstb_restart_nb);
|
||||
rc = devm_register_sys_off_handler(&pdev->dev, SYS_OFF_MODE_RESTART,
|
||||
128, brcmstb_restart_handler, NULL);
|
||||
if (rc)
|
||||
dev_err(&pdev->dev,
|
||||
"cannot register restart handler (err=%d)\n", rc);
|
||||
@ -130,6 +100,12 @@ static int brcmstb_reboot_probe(struct platform_device *pdev)
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match[] = {
|
||||
{ .compatible = "brcm,brcmstb-reboot", .data = &reset_bits_40nm },
|
||||
{ .compatible = "brcm,bcm7038-reboot", .data = &reset_bits_65nm },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver brcmstb_reboot_driver = {
|
||||
.probe = brcmstb_reboot_probe,
|
||||
.driver = {
|
||||
@ -140,7 +116,6 @@ static struct platform_driver brcmstb_reboot_driver = {
|
||||
|
||||
static int __init brcmstb_reboot_init(void)
|
||||
{
|
||||
return platform_driver_probe(&brcmstb_reboot_driver,
|
||||
brcmstb_reboot_probe);
|
||||
return platform_driver_register(&brcmstb_reboot_driver);
|
||||
}
|
||||
subsys_initcall(brcmstb_reboot_init);
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
struct pwr_mlxbf {
|
||||
struct work_struct reboot_work;
|
||||
struct work_struct shutdown_work;
|
||||
const char *hid;
|
||||
};
|
||||
|
||||
@ -27,22 +26,17 @@ static void pwr_mlxbf_reboot_work(struct work_struct *work)
|
||||
acpi_bus_generate_netlink_event("button/reboot.*", "Reboot Button", 0x80, 1);
|
||||
}
|
||||
|
||||
static void pwr_mlxbf_shutdown_work(struct work_struct *work)
|
||||
{
|
||||
acpi_bus_generate_netlink_event("button/power.*", "Power Button", 0x80, 1);
|
||||
}
|
||||
|
||||
static irqreturn_t pwr_mlxbf_irq(int irq, void *ptr)
|
||||
{
|
||||
const char *rst_pwr_hid = "MLNXBF24";
|
||||
const char *low_pwr_hid = "MLNXBF29";
|
||||
const char *shutdown_hid = "MLNXBF29";
|
||||
struct pwr_mlxbf *priv = ptr;
|
||||
|
||||
if (!strncmp(priv->hid, rst_pwr_hid, 8))
|
||||
schedule_work(&priv->reboot_work);
|
||||
|
||||
if (!strncmp(priv->hid, low_pwr_hid, 8))
|
||||
schedule_work(&priv->shutdown_work);
|
||||
if (!strncmp(priv->hid, shutdown_hid, 8))
|
||||
orderly_poweroff(true);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
@ -70,10 +64,6 @@ static int pwr_mlxbf_probe(struct platform_device *pdev)
|
||||
if (irq < 0)
|
||||
return dev_err_probe(dev, irq, "Error getting %s irq.\n", priv->hid);
|
||||
|
||||
err = devm_work_autocancel(dev, &priv->shutdown_work, pwr_mlxbf_shutdown_work);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = devm_work_autocancel(dev, &priv->reboot_work, pwr_mlxbf_reboot_work);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -2531,7 +2531,7 @@ static struct attribute *ab8500_fg_attrs[] = {
|
||||
};
|
||||
ATTRIBUTE_GROUPS(ab8500_fg);
|
||||
|
||||
static struct kobj_type ab8500_fg_ktype = {
|
||||
static const struct kobj_type ab8500_fg_ktype = {
|
||||
.sysfs_ops = &ab8500_fg_sysfs_ops,
|
||||
.default_groups = ab8500_fg_groups,
|
||||
};
|
||||
|
@ -17,6 +17,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
@ -32,9 +33,19 @@
|
||||
#include <linux/mfd/axp20x.h>
|
||||
|
||||
#define AXP20X_PWR_STATUS_BAT_CHARGING BIT(2)
|
||||
#define AXP717_PWR_STATUS_MASK GENMASK(6, 5)
|
||||
#define AXP717_PWR_STATUS_BAT_STANDBY 0
|
||||
#define AXP717_PWR_STATUS_BAT_CHRG 1
|
||||
#define AXP717_PWR_STATUS_BAT_DISCHRG 2
|
||||
|
||||
#define AXP20X_PWR_OP_BATT_PRESENT BIT(5)
|
||||
#define AXP20X_PWR_OP_BATT_ACTIVATED BIT(3)
|
||||
#define AXP717_PWR_OP_BATT_PRESENT BIT(3)
|
||||
|
||||
#define AXP717_BATT_PMU_FAULT_MASK GENMASK(2, 0)
|
||||
#define AXP717_BATT_UVLO_2_5V BIT(2)
|
||||
#define AXP717_BATT_OVER_TEMP BIT(1)
|
||||
#define AXP717_BATT_UNDER_TEMP BIT(0)
|
||||
|
||||
#define AXP209_FG_PERCENT GENMASK(6, 0)
|
||||
#define AXP22X_FG_VALID BIT(7)
|
||||
@ -49,20 +60,51 @@
|
||||
#define AXP22X_CHRG_CTRL1_TGT_4_22V (1 << 5)
|
||||
#define AXP22X_CHRG_CTRL1_TGT_4_24V (3 << 5)
|
||||
|
||||
#define AXP717_CHRG_ENABLE BIT(1)
|
||||
#define AXP717_CHRG_CV_VOLT_MASK GENMASK(2, 0)
|
||||
#define AXP717_CHRG_CV_4_0V 0
|
||||
#define AXP717_CHRG_CV_4_1V 1
|
||||
#define AXP717_CHRG_CV_4_2V 2
|
||||
#define AXP717_CHRG_CV_4_35V 3
|
||||
#define AXP717_CHRG_CV_4_4V 4
|
||||
/* Values 5 and 6 reserved. */
|
||||
#define AXP717_CHRG_CV_5_0V 7
|
||||
|
||||
#define AXP813_CHRG_CTRL1_TGT_4_35V (3 << 5)
|
||||
|
||||
#define AXP20X_CHRG_CTRL1_TGT_CURR GENMASK(3, 0)
|
||||
#define AXP717_ICC_CHARGER_LIM_MASK GENMASK(5, 0)
|
||||
|
||||
#define AXP717_ITERM_CHG_LIM_MASK GENMASK(3, 0)
|
||||
#define AXP717_ITERM_CC_STEP 64000
|
||||
|
||||
#define AXP20X_V_OFF_MASK GENMASK(2, 0)
|
||||
#define AXP717_V_OFF_MASK GENMASK(6, 4)
|
||||
|
||||
#define AXP717_BAT_VMIN_MIN_UV 2600000
|
||||
#define AXP717_BAT_VMIN_MAX_UV 3300000
|
||||
#define AXP717_BAT_VMIN_STEP 100000
|
||||
#define AXP717_BAT_CV_MIN_UV 4000000
|
||||
#define AXP717_BAT_CV_MAX_UV 5000000
|
||||
#define AXP717_BAT_CC_MIN_UA 0
|
||||
#define AXP717_BAT_CC_MAX_UA 3008000
|
||||
|
||||
struct axp20x_batt_ps;
|
||||
|
||||
struct axp_data {
|
||||
int ccc_scale;
|
||||
int ccc_offset;
|
||||
bool has_fg_valid;
|
||||
int ccc_scale;
|
||||
int ccc_offset;
|
||||
unsigned int ccc_reg;
|
||||
unsigned int ccc_mask;
|
||||
bool has_fg_valid;
|
||||
const struct power_supply_desc *bat_ps_desc;
|
||||
int (*get_max_voltage)(struct axp20x_batt_ps *batt, int *val);
|
||||
int (*set_max_voltage)(struct axp20x_batt_ps *batt, int val);
|
||||
int (*cfg_iio_chan)(struct platform_device *pdev,
|
||||
struct axp20x_batt_ps *axp_batt);
|
||||
void (*set_bat_info)(struct platform_device *pdev,
|
||||
struct axp20x_batt_ps *axp_batt,
|
||||
struct power_supply_battery_info *info);
|
||||
};
|
||||
|
||||
struct axp20x_batt_ps {
|
||||
@ -135,6 +177,39 @@ static int axp22x_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp717_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
|
||||
int *val)
|
||||
{
|
||||
int ret, reg;
|
||||
|
||||
ret = regmap_read(axp20x_batt->regmap, AXP717_CV_CHG_SET, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (reg & AXP717_CHRG_CV_VOLT_MASK) {
|
||||
case AXP717_CHRG_CV_4_0V:
|
||||
*val = 4000000;
|
||||
return 0;
|
||||
case AXP717_CHRG_CV_4_1V:
|
||||
*val = 4100000;
|
||||
return 0;
|
||||
case AXP717_CHRG_CV_4_2V:
|
||||
*val = 4200000;
|
||||
return 0;
|
||||
case AXP717_CHRG_CV_4_35V:
|
||||
*val = 4350000;
|
||||
return 0;
|
||||
case AXP717_CHRG_CV_4_4V:
|
||||
*val = 4400000;
|
||||
return 0;
|
||||
case AXP717_CHRG_CV_5_0V:
|
||||
*val = 5000000;
|
||||
return 0;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int axp813_battery_get_max_voltage(struct axp20x_batt_ps *axp20x_batt,
|
||||
int *val)
|
||||
{
|
||||
@ -180,6 +255,21 @@ static int axp20x_get_constant_charge_current(struct axp20x_batt_ps *axp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp717_get_constant_charge_current(struct axp20x_batt_ps *axp,
|
||||
int *val)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(axp->regmap, AXP717_ICC_CHG_SET, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*val = FIELD_GET(AXP717_ICC_CHARGER_LIM_MASK, *val) *
|
||||
axp->data->ccc_scale;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp20x_battery_get_prop(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
@ -303,11 +393,11 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
|
||||
val->intval = reg & AXP209_FG_PERCENT;
|
||||
break;
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
return axp20x_batt->data->get_max_voltage(axp20x_batt,
|
||||
&val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
ret = regmap_read(axp20x_batt->regmap, AXP20X_V_OFF, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -332,6 +422,171 @@ static int axp20x_battery_get_prop(struct power_supply *psy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp717_battery_get_prop(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
|
||||
int ret = 0, reg;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
|
||||
®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val->intval = FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg);
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_STATUS_2,
|
||||
®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (FIELD_GET(AXP717_PWR_STATUS_MASK, reg)) {
|
||||
case AXP717_PWR_STATUS_BAT_STANDBY:
|
||||
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
|
||||
return 0;
|
||||
|
||||
case AXP717_PWR_STATUS_BAT_CHRG:
|
||||
val->intval = POWER_SUPPLY_STATUS_CHARGING;
|
||||
return 0;
|
||||
|
||||
case AXP717_PWR_STATUS_BAT_DISCHRG:
|
||||
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If a fault is detected it must also be cleared; if the
|
||||
* condition persists it should reappear (This is an
|
||||
* assumption, it's actually not documented). A restart was
|
||||
* not sufficient to clear the bit in testing despite the
|
||||
* register listed as POR.
|
||||
*/
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
ret = regmap_read(axp20x_batt->regmap, AXP717_PMU_FAULT,
|
||||
®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
switch (reg & AXP717_BATT_PMU_FAULT_MASK) {
|
||||
case AXP717_BATT_UVLO_2_5V:
|
||||
val->intval = POWER_SUPPLY_HEALTH_DEAD;
|
||||
regmap_update_bits(axp20x_batt->regmap,
|
||||
AXP717_PMU_FAULT,
|
||||
AXP717_BATT_UVLO_2_5V,
|
||||
AXP717_BATT_UVLO_2_5V);
|
||||
return 0;
|
||||
|
||||
case AXP717_BATT_OVER_TEMP:
|
||||
val->intval = POWER_SUPPLY_HEALTH_HOT;
|
||||
regmap_update_bits(axp20x_batt->regmap,
|
||||
AXP717_PMU_FAULT,
|
||||
AXP717_BATT_OVER_TEMP,
|
||||
AXP717_BATT_OVER_TEMP);
|
||||
return 0;
|
||||
|
||||
case AXP717_BATT_UNDER_TEMP:
|
||||
val->intval = POWER_SUPPLY_HEALTH_COLD;
|
||||
regmap_update_bits(axp20x_batt->regmap,
|
||||
AXP717_PMU_FAULT,
|
||||
AXP717_BATT_UNDER_TEMP,
|
||||
AXP717_BATT_UNDER_TEMP);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
val->intval = POWER_SUPPLY_HEALTH_GOOD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
|
||||
ret = axp717_get_constant_charge_current(axp20x_batt,
|
||||
&val->intval);
|
||||
if (ret)
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
/*
|
||||
* The offset of this value is currently unknown and is
|
||||
* not documented in the datasheet. Based on
|
||||
* observation it's assumed to be somewhere around
|
||||
* 450ma. I will leave the value raw for now.
|
||||
*/
|
||||
ret = iio_read_channel_processed(axp20x_batt->batt_chrg_i, &val->intval);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* IIO framework gives mA but Power Supply framework gives uA */
|
||||
val->intval *= 1000;
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
ret = regmap_read(axp20x_batt->regmap, AXP717_ON_INDICATE,
|
||||
®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!FIELD_GET(AXP717_PWR_OP_BATT_PRESENT, reg))
|
||||
return -ENODEV;
|
||||
|
||||
ret = regmap_read(axp20x_batt->regmap,
|
||||
AXP717_BATT_PERCENT_DATA, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Fuel Gauge data takes 7 bits but the stored value seems to be
|
||||
* directly the raw percentage without any scaling to 7 bits.
|
||||
*/
|
||||
val->intval = reg & AXP209_FG_PERCENT;
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
return axp20x_batt->data->get_max_voltage(axp20x_batt,
|
||||
&val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
ret = regmap_read(axp20x_batt->regmap,
|
||||
AXP717_VSYS_V_POWEROFF, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val->intval = AXP717_BAT_VMIN_MIN_UV + AXP717_BAT_VMIN_STEP *
|
||||
(reg & AXP717_V_OFF_MASK);
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
ret = iio_read_channel_processed(axp20x_batt->batt_v,
|
||||
&val->intval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* IIO framework gives mV but Power Supply framework gives uV */
|
||||
val->intval *= 1000;
|
||||
return 0;
|
||||
|
||||
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
|
||||
ret = regmap_read(axp20x_batt->regmap,
|
||||
AXP717_ITERM_CHG_SET, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val->intval = (reg & AXP717_ITERM_CHG_LIM_MASK) * AXP717_ITERM_CC_STEP;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int axp22x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
|
||||
int val)
|
||||
{
|
||||
@ -388,6 +643,35 @@ static int axp20x_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
|
||||
AXP20X_CHRG_CTRL1_TGT_VOLT, val);
|
||||
}
|
||||
|
||||
static int axp717_battery_set_max_voltage(struct axp20x_batt_ps *axp20x_batt,
|
||||
int val)
|
||||
{
|
||||
switch (val) {
|
||||
case 4000000:
|
||||
val = AXP717_CHRG_CV_4_0V;
|
||||
break;
|
||||
|
||||
case 4100000:
|
||||
val = AXP717_CHRG_CV_4_1V;
|
||||
break;
|
||||
|
||||
case 4200000:
|
||||
val = AXP717_CHRG_CV_4_2V;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* AXP717 can go up to 4.35, 4.4, and 5.0 volts which
|
||||
* seem too high for lithium batteries, so do not allow.
|
||||
*/
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return regmap_update_bits(axp20x_batt->regmap,
|
||||
AXP717_CV_CHG_SET,
|
||||
AXP717_CHRG_CV_VOLT_MASK, val);
|
||||
}
|
||||
|
||||
static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt,
|
||||
int charge_current)
|
||||
{
|
||||
@ -404,6 +688,24 @@ static int axp20x_set_constant_charge_current(struct axp20x_batt_ps *axp_batt,
|
||||
AXP20X_CHRG_CTRL1_TGT_CURR, charge_current);
|
||||
}
|
||||
|
||||
static int axp717_set_constant_charge_current(struct axp20x_batt_ps *axp,
|
||||
int charge_current)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (charge_current > axp->max_ccc)
|
||||
return -EINVAL;
|
||||
|
||||
if (charge_current > AXP717_BAT_CC_MAX_UA || charge_current < 0)
|
||||
return -EINVAL;
|
||||
|
||||
val = (charge_current - axp->data->ccc_offset) /
|
||||
axp->data->ccc_scale;
|
||||
|
||||
return regmap_update_bits(axp->regmap, AXP717_ICC_CHG_SET,
|
||||
AXP717_ICC_CHARGER_LIM_MASK, val);
|
||||
}
|
||||
|
||||
static int axp20x_set_max_constant_charge_current(struct axp20x_batt_ps *axp,
|
||||
int charge_current)
|
||||
{
|
||||
@ -448,6 +750,19 @@ static int axp20x_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
|
||||
AXP20X_V_OFF_MASK, val1);
|
||||
}
|
||||
|
||||
static int axp717_set_voltage_min_design(struct axp20x_batt_ps *axp_batt,
|
||||
int min_voltage)
|
||||
{
|
||||
int val1 = (min_voltage - AXP717_BAT_VMIN_MIN_UV) / AXP717_BAT_VMIN_STEP;
|
||||
|
||||
if (val1 < 0 || val1 > AXP717_V_OFF_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
return regmap_update_bits(axp_batt->regmap,
|
||||
AXP717_VSYS_V_POWEROFF,
|
||||
AXP717_V_OFF_MASK, val1);
|
||||
}
|
||||
|
||||
static int axp20x_battery_set_prop(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
const union power_supply_propval *val)
|
||||
@ -455,10 +770,10 @@ static int axp20x_battery_set_prop(struct power_supply *psy,
|
||||
struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
return axp20x_set_voltage_min_design(axp20x_batt, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
|
||||
@ -484,6 +799,42 @@ static int axp20x_battery_set_prop(struct power_supply *psy,
|
||||
}
|
||||
}
|
||||
|
||||
static int axp717_battery_set_prop(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
const union power_supply_propval *val)
|
||||
{
|
||||
struct axp20x_batt_ps *axp20x_batt = power_supply_get_drvdata(psy);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
return axp717_set_voltage_min_design(axp20x_batt, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MAX:
|
||||
return axp20x_batt->data->set_max_voltage(axp20x_batt, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
|
||||
return axp717_set_constant_charge_current(axp20x_batt,
|
||||
val->intval);
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
switch (val->intval) {
|
||||
case POWER_SUPPLY_STATUS_CHARGING:
|
||||
return regmap_update_bits(axp20x_batt->regmap,
|
||||
AXP717_MODULE_EN_CONTROL_2,
|
||||
AXP717_CHRG_ENABLE,
|
||||
AXP717_CHRG_ENABLE);
|
||||
|
||||
case POWER_SUPPLY_STATUS_DISCHARGING:
|
||||
case POWER_SUPPLY_STATUS_NOT_CHARGING:
|
||||
return regmap_update_bits(axp20x_batt->regmap,
|
||||
AXP717_MODULE_EN_CONTROL_2,
|
||||
AXP717_CHRG_ENABLE, 0);
|
||||
}
|
||||
return -EINVAL;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static enum power_supply_property axp20x_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
@ -493,22 +844,45 @@ static enum power_supply_property axp20x_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
};
|
||||
|
||||
static enum power_supply_property axp717_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
POWER_SUPPLY_PROP_CURRENT_NOW,
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MAX,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
|
||||
};
|
||||
|
||||
static int axp20x_battery_prop_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
return psp == POWER_SUPPLY_PROP_STATUS ||
|
||||
psp == POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN ||
|
||||
psp == POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN ||
|
||||
psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
|
||||
psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
|
||||
psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT ||
|
||||
psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
|
||||
}
|
||||
|
||||
static const struct power_supply_desc axp20x_batt_ps_desc = {
|
||||
static int axp717_battery_prop_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
return psp == POWER_SUPPLY_PROP_STATUS ||
|
||||
psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
|
||||
psp == POWER_SUPPLY_PROP_VOLTAGE_MAX ||
|
||||
psp == POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
|
||||
}
|
||||
|
||||
static const struct power_supply_desc axp209_batt_ps_desc = {
|
||||
.name = "axp20x-battery",
|
||||
.type = POWER_SUPPLY_TYPE_BATTERY,
|
||||
.properties = axp20x_battery_props,
|
||||
@ -518,27 +892,163 @@ static const struct power_supply_desc axp20x_batt_ps_desc = {
|
||||
.set_property = axp20x_battery_set_prop,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp717_batt_ps_desc = {
|
||||
.name = "axp20x-battery",
|
||||
.type = POWER_SUPPLY_TYPE_BATTERY,
|
||||
.properties = axp717_battery_props,
|
||||
.num_properties = ARRAY_SIZE(axp717_battery_props),
|
||||
.property_is_writeable = axp717_battery_prop_writeable,
|
||||
.get_property = axp717_battery_get_prop,
|
||||
.set_property = axp717_battery_set_prop,
|
||||
};
|
||||
|
||||
static int axp209_bat_cfg_iio_channels(struct platform_device *pdev,
|
||||
struct axp20x_batt_ps *axp_batt)
|
||||
{
|
||||
axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
|
||||
if (IS_ERR(axp_batt->batt_v)) {
|
||||
if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp_batt->batt_v);
|
||||
}
|
||||
|
||||
axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
|
||||
"batt_chrg_i");
|
||||
if (IS_ERR(axp_batt->batt_chrg_i)) {
|
||||
if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp_batt->batt_chrg_i);
|
||||
}
|
||||
|
||||
axp_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
|
||||
"batt_dischrg_i");
|
||||
if (IS_ERR(axp_batt->batt_dischrg_i)) {
|
||||
if (PTR_ERR(axp_batt->batt_dischrg_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp_batt->batt_dischrg_i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp717_bat_cfg_iio_channels(struct platform_device *pdev,
|
||||
struct axp20x_batt_ps *axp_batt)
|
||||
{
|
||||
axp_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
|
||||
if (IS_ERR(axp_batt->batt_v)) {
|
||||
if (PTR_ERR(axp_batt->batt_v) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp_batt->batt_v);
|
||||
}
|
||||
|
||||
axp_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
|
||||
"batt_chrg_i");
|
||||
if (IS_ERR(axp_batt->batt_chrg_i)) {
|
||||
if (PTR_ERR(axp_batt->batt_chrg_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp_batt->batt_chrg_i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void axp209_set_battery_info(struct platform_device *pdev,
|
||||
struct axp20x_batt_ps *axp_batt,
|
||||
struct power_supply_battery_info *info)
|
||||
{
|
||||
int vmin = info->voltage_min_design_uv;
|
||||
int ccc = info->constant_charge_current_max_ua;
|
||||
|
||||
if (vmin > 0 && axp20x_set_voltage_min_design(axp_batt, vmin))
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set voltage_min_design\n");
|
||||
|
||||
/* Set max to unverified value to be able to set CCC */
|
||||
axp_batt->max_ccc = ccc;
|
||||
|
||||
if (ccc <= 0 || axp20x_set_constant_charge_current(axp_batt, ccc)) {
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set ccc from DT: fallback to min value\n");
|
||||
ccc = 300000;
|
||||
axp_batt->max_ccc = ccc;
|
||||
axp20x_set_constant_charge_current(axp_batt, ccc);
|
||||
}
|
||||
}
|
||||
|
||||
static void axp717_set_battery_info(struct platform_device *pdev,
|
||||
struct axp20x_batt_ps *axp_batt,
|
||||
struct power_supply_battery_info *info)
|
||||
{
|
||||
int vmin = info->voltage_min_design_uv;
|
||||
int vmax = info->voltage_max_design_uv;
|
||||
int ccc = info->constant_charge_current_max_ua;
|
||||
int val;
|
||||
|
||||
if (vmin > 0 && axp717_set_voltage_min_design(axp_batt, vmin))
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set voltage_min_design\n");
|
||||
|
||||
if (vmax > 0 && axp717_battery_set_max_voltage(axp_batt, vmax))
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set voltage_max_design\n");
|
||||
|
||||
axp717_get_constant_charge_current(axp_batt, &val);
|
||||
axp_batt->max_ccc = ccc;
|
||||
if (ccc <= 0 || axp717_set_constant_charge_current(axp_batt, ccc)) {
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set ccc from DT: current ccc is %d\n",
|
||||
val);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct axp_data axp209_data = {
|
||||
.ccc_scale = 100000,
|
||||
.ccc_offset = 300000,
|
||||
.ccc_reg = AXP20X_CHRG_CTRL1,
|
||||
.ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
|
||||
.bat_ps_desc = &axp209_batt_ps_desc,
|
||||
.get_max_voltage = axp20x_battery_get_max_voltage,
|
||||
.set_max_voltage = axp20x_battery_set_max_voltage,
|
||||
.cfg_iio_chan = axp209_bat_cfg_iio_channels,
|
||||
.set_bat_info = axp209_set_battery_info,
|
||||
};
|
||||
|
||||
static const struct axp_data axp221_data = {
|
||||
.ccc_scale = 150000,
|
||||
.ccc_offset = 300000,
|
||||
.ccc_reg = AXP20X_CHRG_CTRL1,
|
||||
.ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
|
||||
.has_fg_valid = true,
|
||||
.bat_ps_desc = &axp209_batt_ps_desc,
|
||||
.get_max_voltage = axp22x_battery_get_max_voltage,
|
||||
.set_max_voltage = axp22x_battery_set_max_voltage,
|
||||
.cfg_iio_chan = axp209_bat_cfg_iio_channels,
|
||||
.set_bat_info = axp209_set_battery_info,
|
||||
};
|
||||
|
||||
static const struct axp_data axp717_data = {
|
||||
.ccc_scale = 64000,
|
||||
.ccc_offset = 0,
|
||||
.ccc_reg = AXP717_ICC_CHG_SET,
|
||||
.ccc_mask = AXP717_ICC_CHARGER_LIM_MASK,
|
||||
.bat_ps_desc = &axp717_batt_ps_desc,
|
||||
.get_max_voltage = axp717_battery_get_max_voltage,
|
||||
.set_max_voltage = axp717_battery_set_max_voltage,
|
||||
.cfg_iio_chan = axp717_bat_cfg_iio_channels,
|
||||
.set_bat_info = axp717_set_battery_info,
|
||||
};
|
||||
|
||||
static const struct axp_data axp813_data = {
|
||||
.ccc_scale = 200000,
|
||||
.ccc_offset = 200000,
|
||||
.ccc_reg = AXP20X_CHRG_CTRL1,
|
||||
.ccc_mask = AXP20X_CHRG_CTRL1_TGT_CURR,
|
||||
.has_fg_valid = true,
|
||||
.bat_ps_desc = &axp209_batt_ps_desc,
|
||||
.get_max_voltage = axp813_battery_get_max_voltage,
|
||||
.set_max_voltage = axp20x_battery_set_max_voltage,
|
||||
.cfg_iio_chan = axp209_bat_cfg_iio_channels,
|
||||
.set_bat_info = axp209_set_battery_info,
|
||||
};
|
||||
|
||||
static const struct of_device_id axp20x_battery_ps_id[] = {
|
||||
@ -548,6 +1058,9 @@ static const struct of_device_id axp20x_battery_ps_id[] = {
|
||||
}, {
|
||||
.compatible = "x-powers,axp221-battery-power-supply",
|
||||
.data = (void *)&axp221_data,
|
||||
}, {
|
||||
.compatible = "x-powers,axp717-battery-power-supply",
|
||||
.data = (void *)&axp717_data,
|
||||
}, {
|
||||
.compatible = "x-powers,axp813-battery-power-supply",
|
||||
.data = (void *)&axp813_data,
|
||||
@ -561,6 +1074,7 @@ static int axp20x_power_probe(struct platform_device *pdev)
|
||||
struct power_supply_config psy_cfg = {};
|
||||
struct power_supply_battery_info *info;
|
||||
struct device *dev = &pdev->dev;
|
||||
int ret;
|
||||
|
||||
if (!of_device_is_available(pdev->dev.of_node))
|
||||
return -ENODEV;
|
||||
@ -572,29 +1086,6 @@ static int axp20x_power_probe(struct platform_device *pdev)
|
||||
|
||||
axp20x_batt->dev = &pdev->dev;
|
||||
|
||||
axp20x_batt->batt_v = devm_iio_channel_get(&pdev->dev, "batt_v");
|
||||
if (IS_ERR(axp20x_batt->batt_v)) {
|
||||
if (PTR_ERR(axp20x_batt->batt_v) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp20x_batt->batt_v);
|
||||
}
|
||||
|
||||
axp20x_batt->batt_chrg_i = devm_iio_channel_get(&pdev->dev,
|
||||
"batt_chrg_i");
|
||||
if (IS_ERR(axp20x_batt->batt_chrg_i)) {
|
||||
if (PTR_ERR(axp20x_batt->batt_chrg_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp20x_batt->batt_chrg_i);
|
||||
}
|
||||
|
||||
axp20x_batt->batt_dischrg_i = devm_iio_channel_get(&pdev->dev,
|
||||
"batt_dischrg_i");
|
||||
if (IS_ERR(axp20x_batt->batt_dischrg_i)) {
|
||||
if (PTR_ERR(axp20x_batt->batt_dischrg_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(axp20x_batt->batt_dischrg_i);
|
||||
}
|
||||
|
||||
axp20x_batt->regmap = dev_get_regmap(pdev->dev.parent, NULL);
|
||||
platform_set_drvdata(pdev, axp20x_batt);
|
||||
|
||||
@ -603,8 +1094,12 @@ static int axp20x_power_probe(struct platform_device *pdev)
|
||||
|
||||
axp20x_batt->data = (struct axp_data *)of_device_get_match_data(dev);
|
||||
|
||||
ret = axp20x_batt->data->cfg_iio_chan(pdev, axp20x_batt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
axp20x_batt->batt = devm_power_supply_register(&pdev->dev,
|
||||
&axp20x_batt_ps_desc,
|
||||
axp20x_batt->data->bat_ps_desc,
|
||||
&psy_cfg);
|
||||
if (IS_ERR(axp20x_batt->batt)) {
|
||||
dev_err(&pdev->dev, "failed to register power supply: %ld\n",
|
||||
@ -613,33 +1108,15 @@ static int axp20x_power_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
if (!power_supply_get_battery_info(axp20x_batt->batt, &info)) {
|
||||
int vmin = info->voltage_min_design_uv;
|
||||
int ccc = info->constant_charge_current_max_ua;
|
||||
|
||||
if (vmin > 0 && axp20x_set_voltage_min_design(axp20x_batt,
|
||||
vmin))
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set voltage_min_design\n");
|
||||
|
||||
/* Set max to unverified value to be able to set CCC */
|
||||
axp20x_batt->max_ccc = ccc;
|
||||
|
||||
if (ccc <= 0 || axp20x_set_constant_charge_current(axp20x_batt,
|
||||
ccc)) {
|
||||
dev_err(&pdev->dev,
|
||||
"couldn't set constant charge current from DT: fallback to minimum value\n");
|
||||
ccc = 300000;
|
||||
axp20x_batt->max_ccc = ccc;
|
||||
axp20x_set_constant_charge_current(axp20x_batt, ccc);
|
||||
}
|
||||
axp20x_batt->data->set_bat_info(pdev, axp20x_batt, info);
|
||||
power_supply_put_battery_info(axp20x_batt->batt, info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update max CCC to a valid value if battery info is present or set it
|
||||
* to current register value by default.
|
||||
*/
|
||||
axp20x_get_constant_charge_current(axp20x_batt,
|
||||
&axp20x_batt->max_ccc);
|
||||
axp20x_get_constant_charge_current(axp20x_batt, &axp20x_batt->max_ccc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -30,8 +30,13 @@
|
||||
#define AXP20X_PWR_STATUS_VBUS_PRESENT BIT(5)
|
||||
#define AXP20X_PWR_STATUS_VBUS_USED BIT(4)
|
||||
|
||||
#define AXP717_PWR_STATUS_VBUS_GOOD BIT(5)
|
||||
|
||||
#define AXP20X_USB_STATUS_VBUS_VALID BIT(2)
|
||||
|
||||
#define AXP717_PMU_FAULT_VBUS BIT(5)
|
||||
#define AXP717_PMU_FAULT_VSYS BIT(3)
|
||||
|
||||
#define AXP20X_VBUS_VHOLD_uV(b) (4000000 + (((b) >> 3) & 7) * 100000)
|
||||
#define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
|
||||
#define AXP20X_VBUS_VHOLD_OFFSET 3
|
||||
@ -39,12 +44,20 @@
|
||||
#define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
|
||||
#define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
|
||||
|
||||
#define AXP717_INPUT_VOL_LIMIT_MASK GENMASK(3, 0)
|
||||
#define AXP717_INPUT_CUR_LIMIT_MASK GENMASK(5, 0)
|
||||
#define AXP717_ADC_DATA_MASK GENMASK(14, 0)
|
||||
|
||||
#define AXP717_ADC_EN_VBUS_VOLT BIT(2)
|
||||
|
||||
/*
|
||||
* Note do not raise the debounce time, we must report Vusb high within
|
||||
* 100ms otherwise we get Vbus errors in musb.
|
||||
*/
|
||||
#define DEBOUNCE_TIME msecs_to_jiffies(50)
|
||||
|
||||
struct axp20x_usb_power;
|
||||
|
||||
struct axp_data {
|
||||
const struct power_supply_desc *power_desc;
|
||||
const char * const *irq_names;
|
||||
@ -58,6 +71,10 @@ struct axp_data {
|
||||
struct reg_field usb_bc_det_fld;
|
||||
struct reg_field vbus_disable_bit;
|
||||
bool vbus_needs_polling: 1;
|
||||
void (*axp20x_read_vbus)(struct work_struct *work);
|
||||
int (*axp20x_cfg_iio_chan)(struct platform_device *pdev,
|
||||
struct axp20x_usb_power *power);
|
||||
int (*axp20x_cfg_adc_reg)(struct axp20x_usb_power *power);
|
||||
};
|
||||
|
||||
struct axp20x_usb_power {
|
||||
@ -74,6 +91,7 @@ struct axp20x_usb_power {
|
||||
struct iio_channel *vbus_v;
|
||||
struct iio_channel *vbus_i;
|
||||
struct delayed_work vbus_detect;
|
||||
int max_input_cur;
|
||||
unsigned int old_status;
|
||||
unsigned int online;
|
||||
unsigned int num_irqs;
|
||||
@ -136,6 +154,24 @@ out:
|
||||
mod_delayed_work(system_power_efficient_wq, &power->vbus_detect, DEBOUNCE_TIME);
|
||||
}
|
||||
|
||||
static void axp717_usb_power_poll_vbus(struct work_struct *work)
|
||||
{
|
||||
struct axp20x_usb_power *power =
|
||||
container_of(work, struct axp20x_usb_power, vbus_detect.work);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &val);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
val &= AXP717_PWR_STATUS_VBUS_GOOD;
|
||||
if (val != power->old_status)
|
||||
power_supply_changed(power->supply);
|
||||
|
||||
power->old_status = val;
|
||||
}
|
||||
|
||||
static int axp20x_get_usb_type(struct axp20x_usb_power *power,
|
||||
union power_supply_propval *val)
|
||||
{
|
||||
@ -281,6 +317,91 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp717_usb_power_get_property(struct power_supply *psy,
|
||||
enum power_supply_property psp, union power_supply_propval *val)
|
||||
{
|
||||
struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
val->intval = POWER_SUPPLY_HEALTH_GOOD;
|
||||
ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &v);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!(v & AXP717_PWR_STATUS_VBUS_GOOD))
|
||||
val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
|
||||
|
||||
ret = regmap_read(power->regmap, AXP717_PMU_FAULT_VBUS, &v);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
v &= (AXP717_PMU_FAULT_VBUS | AXP717_PMU_FAULT_VSYS);
|
||||
if (v) {
|
||||
val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
|
||||
regmap_write(power->regmap, AXP717_PMU_FAULT_VBUS, v);
|
||||
}
|
||||
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
ret = regmap_read(power->regmap, AXP717_INPUT_CUR_LIMIT_CTRL, &v);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 50ma step size with 100ma offset. */
|
||||
v &= AXP717_INPUT_CUR_LIMIT_MASK;
|
||||
val->intval = (v * 50000) + 100000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
ret = regmap_read(power->regmap, AXP717_ON_INDICATE, &v);
|
||||
if (ret)
|
||||
return ret;
|
||||
val->intval = !!(v & AXP717_PWR_STATUS_VBUS_GOOD);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_USB_TYPE:
|
||||
return axp20x_get_usb_type(power, val);
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
ret = regmap_read(power->regmap, AXP717_INPUT_VOL_LIMIT_CTRL, &v);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* 80mv step size with 3.88v offset. */
|
||||
v &= AXP717_INPUT_VOL_LIMIT_MASK;
|
||||
val->intval = (v * 80000) + 3880000;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
if (IS_ENABLED(CONFIG_AXP20X_ADC)) {
|
||||
ret = iio_read_channel_processed(power->vbus_v,
|
||||
&val->intval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* IIO framework gives mV but Power Supply framework
|
||||
* gives uV.
|
||||
*/
|
||||
val->intval *= 1000;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = axp20x_read_variable_width(power->regmap,
|
||||
AXP717_VBUS_V_H, 16);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val->intval = (ret % AXP717_ADC_DATA_MASK) * 1000;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
@ -307,6 +428,22 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int axp717_usb_power_set_voltage_min(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
int val;
|
||||
|
||||
/* Minimum value of 3.88v and maximum of 5.08v. */
|
||||
if (intval < 3880000 || intval > 5080000)
|
||||
return -EINVAL;
|
||||
|
||||
/* step size of 80ma with 3.88v offset. */
|
||||
val = (intval - 3880000) / 80000;
|
||||
return regmap_update_bits(power->regmap,
|
||||
AXP717_INPUT_VOL_LIMIT_CTRL,
|
||||
AXP717_INPUT_VOL_LIMIT_MASK, val);
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
@ -317,6 +454,13 @@ static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *pow
|
||||
if (intval == -1)
|
||||
return -EINVAL;
|
||||
|
||||
if (power->max_input_cur && (intval > power->max_input_cur)) {
|
||||
dev_warn(power->dev,
|
||||
"requested current %d clamped to max current %d\n",
|
||||
intval, power->max_input_cur);
|
||||
intval = power->max_input_cur;
|
||||
}
|
||||
|
||||
/*
|
||||
* BC1.2 detection can cause a race condition if we try to set a current
|
||||
* limit while it's in progress. When it finishes it will overwrite the
|
||||
@ -340,6 +484,29 @@ static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *pow
|
||||
return regmap_field_write(power->curr_lim_fld, reg);
|
||||
}
|
||||
|
||||
static int axp717_usb_power_set_input_current_limit(struct axp20x_usb_power *power,
|
||||
int intval)
|
||||
{
|
||||
int tmp;
|
||||
|
||||
/* Minimum value of 100mA and maximum value of 3.25A*/
|
||||
if (intval < 100000 || intval > 3250000)
|
||||
return -EINVAL;
|
||||
|
||||
if (power->max_input_cur && (intval > power->max_input_cur)) {
|
||||
dev_warn(power->dev,
|
||||
"reqested current %d clamped to max current %d\n",
|
||||
intval, power->max_input_cur);
|
||||
intval = power->max_input_cur;
|
||||
}
|
||||
|
||||
/* Minimum value of 100mA with step size of 50mA. */
|
||||
tmp = (intval - 100000) / 50000;
|
||||
return regmap_update_bits(power->regmap,
|
||||
AXP717_INPUT_CUR_LIMIT_CTRL,
|
||||
AXP717_INPUT_CUR_LIMIT_MASK, tmp);
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_set_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
const union power_supply_propval *val)
|
||||
@ -362,6 +529,24 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int axp717_usb_power_set_property(struct power_supply *psy,
|
||||
enum power_supply_property psp,
|
||||
const union power_supply_propval *val)
|
||||
{
|
||||
struct axp20x_usb_power *power = power_supply_get_drvdata(psy);
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
return axp717_usb_power_set_input_current_limit(power, val->intval);
|
||||
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_MIN:
|
||||
return axp717_usb_power_set_voltage_min(power, val->intval);
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -385,6 +570,64 @@ static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
|
||||
psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
|
||||
}
|
||||
|
||||
static int axp717_usb_power_prop_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
|
||||
psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
|
||||
}
|
||||
|
||||
static int axp20x_configure_iio_channels(struct platform_device *pdev,
|
||||
struct axp20x_usb_power *power)
|
||||
{
|
||||
power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
|
||||
if (IS_ERR(power->vbus_v)) {
|
||||
if (PTR_ERR(power->vbus_v) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(power->vbus_v);
|
||||
}
|
||||
|
||||
power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i");
|
||||
if (IS_ERR(power->vbus_i)) {
|
||||
if (PTR_ERR(power->vbus_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(power->vbus_i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp717_configure_iio_channels(struct platform_device *pdev,
|
||||
struct axp20x_usb_power *power)
|
||||
{
|
||||
power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
|
||||
if (IS_ERR(power->vbus_v)) {
|
||||
if (PTR_ERR(power->vbus_v) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(power->vbus_v);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp20x_configure_adc_registers(struct axp20x_usb_power *power)
|
||||
{
|
||||
/* Enable vbus voltage and current measurement */
|
||||
return regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
|
||||
AXP20X_ADC_EN1_VBUS_CURR |
|
||||
AXP20X_ADC_EN1_VBUS_VOLT,
|
||||
AXP20X_ADC_EN1_VBUS_CURR |
|
||||
AXP20X_ADC_EN1_VBUS_VOLT);
|
||||
}
|
||||
|
||||
static int axp717_configure_adc_registers(struct axp20x_usb_power *power)
|
||||
{
|
||||
/* Enable vbus voltage measurement */
|
||||
return regmap_update_bits(power->regmap, AXP717_ADC_CH_EN_CONTROL,
|
||||
AXP717_ADC_EN_VBUS_VOLT,
|
||||
AXP717_ADC_EN_VBUS_VOLT);
|
||||
}
|
||||
|
||||
static enum power_supply_property axp20x_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
@ -403,6 +646,16 @@ static enum power_supply_property axp22x_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
};
|
||||
|
||||
static enum power_supply_property axp717_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_MIN,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
};
|
||||
|
||||
static enum power_supply_property axp813_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
@ -412,13 +665,6 @@ static enum power_supply_property axp813_usb_power_properties[] = {
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type axp813_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp20x_usb_power_desc = {
|
||||
.name = "axp20x-usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
@ -439,6 +685,20 @@ static const struct power_supply_desc axp22x_usb_power_desc = {
|
||||
.set_property = axp20x_usb_power_set_property,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp717_usb_power_desc = {
|
||||
.name = "axp20x-usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.properties = axp717_usb_power_properties,
|
||||
.num_properties = ARRAY_SIZE(axp717_usb_power_properties),
|
||||
.property_is_writeable = axp717_usb_power_prop_writeable,
|
||||
.get_property = axp717_usb_power_get_property,
|
||||
.set_property = axp717_usb_power_set_property,
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
static const struct power_supply_desc axp813_usb_power_desc = {
|
||||
.name = "axp20x-usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
@ -447,8 +707,10 @@ static const struct power_supply_desc axp813_usb_power_desc = {
|
||||
.property_is_writeable = axp20x_usb_power_prop_writeable,
|
||||
.get_property = axp20x_usb_power_get_property,
|
||||
.set_property = axp20x_usb_power_set_property,
|
||||
.usb_types = axp813_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(axp813_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
static const char * const axp20x_irq_names[] = {
|
||||
@ -463,6 +725,12 @@ static const char * const axp22x_irq_names[] = {
|
||||
"VBUS_REMOVAL",
|
||||
};
|
||||
|
||||
static const char * const axp717_irq_names[] = {
|
||||
"VBUS_PLUGIN",
|
||||
"VBUS_REMOVAL",
|
||||
"VBUS_OVER_V",
|
||||
};
|
||||
|
||||
static int axp192_usb_curr_lim_table[] = {
|
||||
-1,
|
||||
-1,
|
||||
@ -505,6 +773,9 @@ static const struct axp_data axp192_data = {
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_valid_bit = REG_FIELD(AXP192_USB_OTG_STATUS, 2, 2),
|
||||
.vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
|
||||
.axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
|
||||
.axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
|
||||
.axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
|
||||
};
|
||||
|
||||
static const struct axp_data axp202_data = {
|
||||
@ -516,6 +787,9 @@ static const struct axp_data axp202_data = {
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_valid_bit = REG_FIELD(AXP20X_USB_OTG_STATUS, 2, 2),
|
||||
.vbus_mon_bit = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
|
||||
.axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
|
||||
.axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
|
||||
.axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
|
||||
};
|
||||
|
||||
static const struct axp_data axp221_data = {
|
||||
@ -526,6 +800,9 @@ static const struct axp_data axp221_data = {
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp221_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_needs_polling = true,
|
||||
.axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
|
||||
.axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
|
||||
.axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
|
||||
};
|
||||
|
||||
static const struct axp_data axp223_data = {
|
||||
@ -536,6 +813,23 @@ static const struct axp_data axp223_data = {
|
||||
.curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table),
|
||||
.curr_lim_fld = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
|
||||
.vbus_needs_polling = true,
|
||||
.axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
|
||||
.axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
|
||||
.axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
|
||||
};
|
||||
|
||||
static const struct axp_data axp717_data = {
|
||||
.power_desc = &axp717_usb_power_desc,
|
||||
.irq_names = axp717_irq_names,
|
||||
.num_irq_names = ARRAY_SIZE(axp717_irq_names),
|
||||
.curr_lim_fld = REG_FIELD(AXP717_INPUT_CUR_LIMIT_CTRL, 0, 5),
|
||||
.usb_bc_en_bit = REG_FIELD(AXP717_MODULE_EN_CONTROL_1, 4, 4),
|
||||
.usb_bc_det_fld = REG_FIELD(AXP717_BC_DETECT, 5, 7),
|
||||
.vbus_mon_bit = REG_FIELD(AXP717_ADC_CH_EN_CONTROL, 2, 2),
|
||||
.vbus_needs_polling = false,
|
||||
.axp20x_read_vbus = &axp717_usb_power_poll_vbus,
|
||||
.axp20x_cfg_iio_chan = axp717_configure_iio_channels,
|
||||
.axp20x_cfg_adc_reg = axp717_configure_adc_registers,
|
||||
};
|
||||
|
||||
static const struct axp_data axp813_data = {
|
||||
@ -549,6 +843,9 @@ static const struct axp_data axp813_data = {
|
||||
.usb_bc_det_fld = REG_FIELD(AXP288_BC_DET_STAT, 5, 7),
|
||||
.vbus_disable_bit = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 7, 7),
|
||||
.vbus_needs_polling = true,
|
||||
.axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
|
||||
.axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
|
||||
.axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
@ -590,36 +887,6 @@ static int axp20x_usb_power_resume(struct device *dev)
|
||||
static SIMPLE_DEV_PM_OPS(axp20x_usb_power_pm_ops, axp20x_usb_power_suspend,
|
||||
axp20x_usb_power_resume);
|
||||
|
||||
static int configure_iio_channels(struct platform_device *pdev,
|
||||
struct axp20x_usb_power *power)
|
||||
{
|
||||
power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
|
||||
if (IS_ERR(power->vbus_v)) {
|
||||
if (PTR_ERR(power->vbus_v) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(power->vbus_v);
|
||||
}
|
||||
|
||||
power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i");
|
||||
if (IS_ERR(power->vbus_i)) {
|
||||
if (PTR_ERR(power->vbus_i) == -ENODEV)
|
||||
return -EPROBE_DEFER;
|
||||
return PTR_ERR(power->vbus_i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int configure_adc_registers(struct axp20x_usb_power *power)
|
||||
{
|
||||
/* Enable vbus voltage and current measurement */
|
||||
return regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
|
||||
AXP20X_ADC_EN1_VBUS_CURR |
|
||||
AXP20X_ADC_EN1_VBUS_VOLT,
|
||||
AXP20X_ADC_EN1_VBUS_CURR |
|
||||
AXP20X_ADC_EN1_VBUS_VOLT);
|
||||
}
|
||||
|
||||
static int axp20x_regmap_field_alloc_optional(struct device *dev,
|
||||
struct regmap *regmap,
|
||||
struct reg_field fdesc,
|
||||
@ -640,6 +907,18 @@ static int axp20x_regmap_field_alloc_optional(struct device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Optionally allow users to specify a maximum charging current. */
|
||||
static void axp20x_usb_power_parse_dt(struct device *dev,
|
||||
struct axp20x_usb_power *power)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = device_property_read_u32(dev, "input-current-limit-microamp",
|
||||
&power->max_input_cur);
|
||||
if (ret)
|
||||
dev_dbg(dev, "%s() no input-current-limit specified\n", __func__);
|
||||
}
|
||||
|
||||
static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
@ -676,6 +955,8 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(power->curr_lim_fld))
|
||||
return PTR_ERR(power->curr_lim_fld);
|
||||
|
||||
axp20x_usb_power_parse_dt(&pdev->dev, power);
|
||||
|
||||
ret = axp20x_regmap_field_alloc_optional(&pdev->dev, power->regmap,
|
||||
axp_data->vbus_valid_bit,
|
||||
&power->vbus_valid_bit);
|
||||
@ -707,7 +988,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
ret = devm_delayed_work_autocancel(&pdev->dev, &power->vbus_detect,
|
||||
axp20x_usb_power_poll_vbus);
|
||||
axp_data->axp20x_read_vbus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -718,9 +999,9 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
|
||||
if (IS_ENABLED(CONFIG_AXP20X_ADC))
|
||||
ret = configure_iio_channels(pdev, power);
|
||||
ret = axp_data->axp20x_cfg_iio_chan(pdev, power);
|
||||
else
|
||||
ret = configure_adc_registers(power);
|
||||
ret = axp_data->axp20x_cfg_adc_reg(power);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -778,6 +1059,9 @@ static const struct of_device_id axp20x_usb_power_match[] = {
|
||||
}, {
|
||||
.compatible = "x-powers,axp223-usb-power-supply",
|
||||
.data = &axp223_data,
|
||||
}, {
|
||||
.compatible = "x-powers,axp717-usb-power-supply",
|
||||
.data = &axp717_data,
|
||||
}, {
|
||||
.compatible = "x-powers,axp813-usb-power-supply",
|
||||
.data = &axp813_data,
|
||||
|
@ -334,14 +334,6 @@ static const int bq25618_619_ichg_values[] = {
|
||||
1290000, 1360000, 1430000, 1500000
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type bq256xx_usb_type[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_ACA,
|
||||
};
|
||||
|
||||
static int bq256xx_array_parse(int array_size, int val, const int array[])
|
||||
{
|
||||
int i = 0;
|
||||
@ -1252,8 +1244,11 @@ static int bq256xx_property_is_writeable(struct power_supply *psy,
|
||||
static const struct power_supply_desc bq256xx_power_supply_desc = {
|
||||
.name = "bq256xx-charger",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = bq256xx_usb_type,
|
||||
.num_usb_types = ARRAY_SIZE(bq256xx_usb_type),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_ACA) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = bq256xx_power_supply_props,
|
||||
.num_properties = ARRAY_SIZE(bq256xx_power_supply_props),
|
||||
.get_property = bq256xx_get_charger_property,
|
||||
|
@ -904,7 +904,7 @@ static int cpcap_charger_probe(struct platform_device *pdev)
|
||||
psy_cfg.of_node = pdev->dev.of_node;
|
||||
psy_cfg.drv_data = ddata;
|
||||
psy_cfg.supplied_to = cpcap_charger_supplied_to;
|
||||
psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to),
|
||||
psy_cfg.num_supplicants = ARRAY_SIZE(cpcap_charger_supplied_to);
|
||||
|
||||
ddata->usb = devm_power_supply_register(ddata->dev,
|
||||
&cpcap_charger_usb_desc,
|
||||
|
@ -73,17 +73,6 @@ static enum power_supply_property cros_usbpd_dedicated_charger_props[] = {
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type cros_usbpd_charger_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_PD_DRP,
|
||||
POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID
|
||||
};
|
||||
|
||||
/* Input voltage/current limit in mV/mA. Default to none. */
|
||||
static u16 input_voltage_limit = EC_POWER_LIMIT_NONE;
|
||||
static u16 input_current_limit = EC_POWER_LIMIT_NONE;
|
||||
@ -643,9 +632,14 @@ static int cros_usbpd_charger_probe(struct platform_device *pd)
|
||||
psy_desc->properties = cros_usbpd_charger_props;
|
||||
psy_desc->num_properties =
|
||||
ARRAY_SIZE(cros_usbpd_charger_props);
|
||||
psy_desc->usb_types = cros_usbpd_charger_usb_types;
|
||||
psy_desc->num_usb_types =
|
||||
ARRAY_SIZE(cros_usbpd_charger_usb_types);
|
||||
psy_desc->usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID);
|
||||
}
|
||||
|
||||
psy_desc->name = port->name;
|
||||
|
@ -353,15 +353,10 @@ static enum power_supply_property yoga_c630_psy_adpt_properties[] = {
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
};
|
||||
|
||||
static const enum power_supply_usb_type yoga_c630_psy_adpt_usb_type[] = {
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc yoga_c630_psy_adpt_psy_desc = {
|
||||
.name = "yoga-c630-adapter",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = yoga_c630_psy_adpt_usb_type,
|
||||
.num_usb_types = ARRAY_SIZE(yoga_c630_psy_adpt_usb_type),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C),
|
||||
.properties = yoga_c630_psy_adpt_properties,
|
||||
.num_properties = ARRAY_SIZE(yoga_c630_psy_adpt_properties),
|
||||
.get_property = yoga_c630_psy_adpt_get_property,
|
||||
|
@ -853,7 +853,10 @@ static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off)
|
||||
/* program interrupt thresholds such that we should
|
||||
* get interrupt for every 'off' perc change in the soc
|
||||
*/
|
||||
regmap_read(map, MAX17042_RepSOC, &soc);
|
||||
if (chip->pdata->enable_current_sense)
|
||||
regmap_read(map, MAX17042_RepSOC, &soc);
|
||||
else
|
||||
regmap_read(map, MAX17042_VFSOC, &soc);
|
||||
soc >>= 8;
|
||||
soc_tr = (soc + off) << 8;
|
||||
if (off < soc)
|
||||
|
@ -10,13 +10,16 @@
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-provider.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
/* Nonvolatile registers */
|
||||
#define MAX1720X_NXTABLE0 0x80
|
||||
#define MAX1720X_NRSENSE 0xCF /* RSense in 10^-5 Ohm */
|
||||
#define MAX1720X_NDEVICE_NAME4 0xDF
|
||||
|
||||
/* ModelGauge m5 */
|
||||
#define MAX172XX_STATUS 0x00 /* Status */
|
||||
@ -46,6 +49,8 @@ static const char *const max17205_model = "MAX17205";
|
||||
|
||||
struct max1720x_device_info {
|
||||
struct regmap *regmap;
|
||||
struct regmap *regmap_nv;
|
||||
struct i2c_client *ancillary;
|
||||
int rsense;
|
||||
};
|
||||
|
||||
@ -106,6 +111,134 @@ static const struct regmap_config max1720x_regmap_cfg = {
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_range max1720x_nvmem_allow[] = {
|
||||
regmap_reg_range(MAX1720X_NXTABLE0, MAX1720X_NDEVICE_NAME4),
|
||||
};
|
||||
|
||||
static const struct regmap_range max1720x_nvmem_deny[] = {
|
||||
regmap_reg_range(0x00, 0x7F),
|
||||
regmap_reg_range(0xE0, 0xFF),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table max1720x_nvmem_regs = {
|
||||
.yes_ranges = max1720x_nvmem_allow,
|
||||
.n_yes_ranges = ARRAY_SIZE(max1720x_nvmem_allow),
|
||||
.no_ranges = max1720x_nvmem_deny,
|
||||
.n_no_ranges = ARRAY_SIZE(max1720x_nvmem_deny),
|
||||
};
|
||||
|
||||
static const struct regmap_config max1720x_nvmem_regmap_cfg = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 16,
|
||||
.max_register = MAX1720X_NDEVICE_NAME4,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
.rd_table = &max1720x_nvmem_regs,
|
||||
};
|
||||
|
||||
static const struct nvmem_cell_info max1720x_nvmem_cells[] = {
|
||||
{ .name = "nXTable0", .offset = 0, .bytes = 2, },
|
||||
{ .name = "nXTable1", .offset = 2, .bytes = 2, },
|
||||
{ .name = "nXTable2", .offset = 4, .bytes = 2, },
|
||||
{ .name = "nXTable3", .offset = 6, .bytes = 2, },
|
||||
{ .name = "nXTable4", .offset = 8, .bytes = 2, },
|
||||
{ .name = "nXTable5", .offset = 10, .bytes = 2, },
|
||||
{ .name = "nXTable6", .offset = 12, .bytes = 2, },
|
||||
{ .name = "nXTable7", .offset = 14, .bytes = 2, },
|
||||
{ .name = "nXTable8", .offset = 16, .bytes = 2, },
|
||||
{ .name = "nXTable9", .offset = 18, .bytes = 2, },
|
||||
{ .name = "nXTable10", .offset = 20, .bytes = 2, },
|
||||
{ .name = "nXTable11", .offset = 22, .bytes = 2, },
|
||||
{ .name = "nUser18C", .offset = 24, .bytes = 2, },
|
||||
{ .name = "nUser18D", .offset = 26, .bytes = 2, },
|
||||
{ .name = "nODSCTh", .offset = 28, .bytes = 2, },
|
||||
{ .name = "nODSCCfg", .offset = 30, .bytes = 2, },
|
||||
|
||||
{ .name = "nOCVTable0", .offset = 32, .bytes = 2, },
|
||||
{ .name = "nOCVTable1", .offset = 34, .bytes = 2, },
|
||||
{ .name = "nOCVTable2", .offset = 36, .bytes = 2, },
|
||||
{ .name = "nOCVTable3", .offset = 38, .bytes = 2, },
|
||||
{ .name = "nOCVTable4", .offset = 40, .bytes = 2, },
|
||||
{ .name = "nOCVTable5", .offset = 42, .bytes = 2, },
|
||||
{ .name = "nOCVTable6", .offset = 44, .bytes = 2, },
|
||||
{ .name = "nOCVTable7", .offset = 46, .bytes = 2, },
|
||||
{ .name = "nOCVTable8", .offset = 48, .bytes = 2, },
|
||||
{ .name = "nOCVTable9", .offset = 50, .bytes = 2, },
|
||||
{ .name = "nOCVTable10", .offset = 52, .bytes = 2, },
|
||||
{ .name = "nOCVTable11", .offset = 54, .bytes = 2, },
|
||||
{ .name = "nIChgTerm", .offset = 56, .bytes = 2, },
|
||||
{ .name = "nFilterCfg", .offset = 58, .bytes = 2, },
|
||||
{ .name = "nVEmpty", .offset = 60, .bytes = 2, },
|
||||
{ .name = "nLearnCfg", .offset = 62, .bytes = 2, },
|
||||
|
||||
{ .name = "nQRTable00", .offset = 64, .bytes = 2, },
|
||||
{ .name = "nQRTable10", .offset = 66, .bytes = 2, },
|
||||
{ .name = "nQRTable20", .offset = 68, .bytes = 2, },
|
||||
{ .name = "nQRTable30", .offset = 70, .bytes = 2, },
|
||||
{ .name = "nCycles", .offset = 72, .bytes = 2, },
|
||||
{ .name = "nFullCapNom", .offset = 74, .bytes = 2, },
|
||||
{ .name = "nRComp0", .offset = 76, .bytes = 2, },
|
||||
{ .name = "nTempCo", .offset = 78, .bytes = 2, },
|
||||
{ .name = "nIAvgEmpty", .offset = 80, .bytes = 2, },
|
||||
{ .name = "nFullCapRep", .offset = 82, .bytes = 2, },
|
||||
{ .name = "nVoltTemp", .offset = 84, .bytes = 2, },
|
||||
{ .name = "nMaxMinCurr", .offset = 86, .bytes = 2, },
|
||||
{ .name = "nMaxMinVolt", .offset = 88, .bytes = 2, },
|
||||
{ .name = "nMaxMinTemp", .offset = 90, .bytes = 2, },
|
||||
{ .name = "nSOC", .offset = 92, .bytes = 2, },
|
||||
{ .name = "nTimerH", .offset = 94, .bytes = 2, },
|
||||
|
||||
{ .name = "nConfig", .offset = 96, .bytes = 2, },
|
||||
{ .name = "nRippleCfg", .offset = 98, .bytes = 2, },
|
||||
{ .name = "nMiscCfg", .offset = 100, .bytes = 2, },
|
||||
{ .name = "nDesignCap", .offset = 102, .bytes = 2, },
|
||||
{ .name = "nHibCfg", .offset = 104, .bytes = 2, },
|
||||
{ .name = "nPackCfg", .offset = 106, .bytes = 2, },
|
||||
{ .name = "nRelaxCfg", .offset = 108, .bytes = 2, },
|
||||
{ .name = "nConvgCfg", .offset = 110, .bytes = 2, },
|
||||
{ .name = "nNVCfg0", .offset = 112, .bytes = 2, },
|
||||
{ .name = "nNVCfg1", .offset = 114, .bytes = 2, },
|
||||
{ .name = "nNVCfg2", .offset = 116, .bytes = 2, },
|
||||
{ .name = "nSBSCfg", .offset = 118, .bytes = 2, },
|
||||
{ .name = "nROMID0", .offset = 120, .bytes = 2, },
|
||||
{ .name = "nROMID1", .offset = 122, .bytes = 2, },
|
||||
{ .name = "nROMID2", .offset = 124, .bytes = 2, },
|
||||
{ .name = "nROMID3", .offset = 126, .bytes = 2, },
|
||||
|
||||
{ .name = "nVAlrtTh", .offset = 128, .bytes = 2, },
|
||||
{ .name = "nTAlrtTh", .offset = 130, .bytes = 2, },
|
||||
{ .name = "nSAlrtTh", .offset = 132, .bytes = 2, },
|
||||
{ .name = "nIAlrtTh", .offset = 134, .bytes = 2, },
|
||||
{ .name = "nUser1C4", .offset = 136, .bytes = 2, },
|
||||
{ .name = "nUser1C5", .offset = 138, .bytes = 2, },
|
||||
{ .name = "nFullSOCThr", .offset = 140, .bytes = 2, },
|
||||
{ .name = "nTTFCfg", .offset = 142, .bytes = 2, },
|
||||
{ .name = "nCGain", .offset = 144, .bytes = 2, },
|
||||
{ .name = "nTCurve", .offset = 146, .bytes = 2, },
|
||||
{ .name = "nTGain", .offset = 148, .bytes = 2, },
|
||||
{ .name = "nTOff", .offset = 150, .bytes = 2, },
|
||||
{ .name = "nManfctrName0", .offset = 152, .bytes = 2, },
|
||||
{ .name = "nManfctrName1", .offset = 154, .bytes = 2, },
|
||||
{ .name = "nManfctrName2", .offset = 156, .bytes = 2, },
|
||||
{ .name = "nRSense", .offset = 158, .bytes = 2, },
|
||||
|
||||
{ .name = "nUser1D0", .offset = 160, .bytes = 2, },
|
||||
{ .name = "nUser1D1", .offset = 162, .bytes = 2, },
|
||||
{ .name = "nAgeFcCfg", .offset = 164, .bytes = 2, },
|
||||
{ .name = "nDesignVoltage", .offset = 166, .bytes = 2, },
|
||||
{ .name = "nUser1D4", .offset = 168, .bytes = 2, },
|
||||
{ .name = "nRFastVShdn", .offset = 170, .bytes = 2, },
|
||||
{ .name = "nManfctrDate", .offset = 172, .bytes = 2, },
|
||||
{ .name = "nFirstUsed", .offset = 174, .bytes = 2, },
|
||||
{ .name = "nSerialNumber0", .offset = 176, .bytes = 2, },
|
||||
{ .name = "nSerialNumber1", .offset = 178, .bytes = 2, },
|
||||
{ .name = "nSerialNumber2", .offset = 180, .bytes = 2, },
|
||||
{ .name = "nDeviceName0", .offset = 182, .bytes = 2, },
|
||||
{ .name = "nDeviceName1", .offset = 184, .bytes = 2, },
|
||||
{ .name = "nDeviceName2", .offset = 186, .bytes = 2, },
|
||||
{ .name = "nDeviceName3", .offset = 188, .bytes = 2, },
|
||||
{ .name = "nDeviceName4", .offset = 190, .bytes = 2, },
|
||||
};
|
||||
|
||||
static const enum power_supply_property max1720x_battery_props[] = {
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_CAPACITY,
|
||||
@ -249,30 +382,80 @@ static int max1720x_battery_get_property(struct power_supply *psy,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max1720x_probe_sense_resistor(struct i2c_client *client,
|
||||
struct max1720x_device_info *info)
|
||||
static
|
||||
int max1720x_nvmem_reg_read(void *priv, unsigned int off, void *val, size_t len)
|
||||
{
|
||||
struct max1720x_device_info *info = priv;
|
||||
unsigned int reg = MAX1720X_NXTABLE0 + (off / 2);
|
||||
|
||||
return regmap_bulk_read(info->regmap_nv, reg, val, len / 2);
|
||||
}
|
||||
|
||||
static void max1720x_unregister_ancillary(void *data)
|
||||
{
|
||||
struct max1720x_device_info *info = data;
|
||||
|
||||
i2c_unregister_device(info->ancillary);
|
||||
}
|
||||
|
||||
static int max1720x_probe_nvmem(struct i2c_client *client,
|
||||
struct max1720x_device_info *info)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct i2c_client *ancillary;
|
||||
struct nvmem_config nvmem_config = {
|
||||
.dev = dev,
|
||||
.name = "max1720x_nvmem",
|
||||
.cells = max1720x_nvmem_cells,
|
||||
.ncells = ARRAY_SIZE(max1720x_nvmem_cells),
|
||||
.read_only = true,
|
||||
.root_only = true,
|
||||
.reg_read = max1720x_nvmem_reg_read,
|
||||
.size = ARRAY_SIZE(max1720x_nvmem_cells) * 2,
|
||||
.word_size = 2,
|
||||
.stride = 2,
|
||||
.priv = info,
|
||||
};
|
||||
struct nvmem_device *nvmem;
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
ancillary = i2c_new_ancillary_device(client, "nvmem", 0xb);
|
||||
if (IS_ERR(ancillary)) {
|
||||
info->ancillary = i2c_new_ancillary_device(client, "nvmem", 0xb);
|
||||
if (IS_ERR(info->ancillary)) {
|
||||
dev_err(dev, "Failed to initialize ancillary i2c device\n");
|
||||
return PTR_ERR(ancillary);
|
||||
return PTR_ERR(info->ancillary);
|
||||
}
|
||||
|
||||
ret = i2c_smbus_read_word_data(ancillary, MAX1720X_NRSENSE);
|
||||
i2c_unregister_device(ancillary);
|
||||
if (ret < 0)
|
||||
ret = devm_add_action_or_reset(dev, max1720x_unregister_ancillary, info);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to add unregister callback\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
info->rsense = ret;
|
||||
info->regmap_nv = devm_regmap_init_i2c(info->ancillary,
|
||||
&max1720x_nvmem_regmap_cfg);
|
||||
if (IS_ERR(info->regmap_nv)) {
|
||||
dev_err(dev, "regmap initialization of nvmem failed\n");
|
||||
return PTR_ERR(info->regmap_nv);
|
||||
}
|
||||
|
||||
ret = regmap_read(info->regmap_nv, MAX1720X_NRSENSE, &val);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to read sense resistor value\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
info->rsense = val;
|
||||
if (!info->rsense) {
|
||||
dev_warn(dev, "RSense not calibrated, set 10 mOhms!\n");
|
||||
info->rsense = 1000; /* in regs in 10^-5 */
|
||||
}
|
||||
|
||||
nvmem = devm_nvmem_register(dev, &nvmem_config);
|
||||
if (IS_ERR(nvmem)) {
|
||||
dev_err(dev, "Could not register nvmem!");
|
||||
return PTR_ERR(nvmem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -299,15 +482,15 @@ static int max1720x_probe(struct i2c_client *client)
|
||||
|
||||
psy_cfg.drv_data = info;
|
||||
psy_cfg.fwnode = dev_fwnode(dev);
|
||||
i2c_set_clientdata(client, info);
|
||||
info->regmap = devm_regmap_init_i2c(client, &max1720x_regmap_cfg);
|
||||
if (IS_ERR(info->regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(info->regmap),
|
||||
"regmap initialization failed\n");
|
||||
|
||||
ret = max1720x_probe_sense_resistor(client, info);
|
||||
ret = max1720x_probe_nvmem(client, info);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret,
|
||||
"Failed to read sense resistor value\n");
|
||||
return dev_err_probe(dev, ret, "Failed to probe nvmem\n");
|
||||
|
||||
bat = devm_power_supply_register(dev, &max1720x_bat_desc, &psy_cfg);
|
||||
if (IS_ERR(bat))
|
||||
|
@ -197,12 +197,58 @@ static int max77693_get_online(struct regmap *regmap, int *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are *two* current limit registers:
|
||||
* - CHGIN limit, which limits the input current from the external charger;
|
||||
* - Fast charge current limit, which limits the current going to the battery.
|
||||
*/
|
||||
|
||||
static int max77693_get_input_current_limit(struct regmap *regmap, int *val)
|
||||
{
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_09, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data &= CHG_CNFG_09_CHGIN_ILIM_MASK;
|
||||
data >>= CHG_CNFG_09_CHGIN_ILIM_SHIFT;
|
||||
|
||||
if (data <= 0x03)
|
||||
/* The first four values (0x00..0x03) are 60mA */
|
||||
*val = 60000;
|
||||
else
|
||||
*val = data * 20000; /* 20mA steps */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max77693_get_fast_charge_current(struct regmap *regmap, int *val)
|
||||
{
|
||||
unsigned int data;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(regmap, MAX77693_CHG_REG_CHG_CNFG_02, &data);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
data &= CHG_CNFG_02_CC_MASK;
|
||||
data >>= CHG_CNFG_02_CC_SHIFT;
|
||||
|
||||
*val = data * 33300; /* 33.3mA steps */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum power_supply_property max77693_charger_props[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_CHARGE_TYPE,
|
||||
POWER_SUPPLY_PROP_HEALTH,
|
||||
POWER_SUPPLY_PROP_PRESENT,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
|
||||
POWER_SUPPLY_PROP_MODEL_NAME,
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
};
|
||||
@ -231,6 +277,12 @@ static int max77693_charger_get_property(struct power_supply *psy,
|
||||
case POWER_SUPPLY_PROP_ONLINE:
|
||||
ret = max77693_get_online(regmap, &val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
|
||||
ret = max77693_get_input_current_limit(regmap, &val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
|
||||
ret = max77693_get_fast_charge_current(regmap, &val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_MODEL_NAME:
|
||||
val->strval = max77693_charger_model;
|
||||
break;
|
||||
|
@ -191,6 +191,7 @@ static const struct platform_device_id max8998_battery_id[] = {
|
||||
{ "max8998-battery", TYPE_MAX8998 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, max8998_battery_id);
|
||||
|
||||
static struct platform_driver max8998_battery_driver = {
|
||||
.driver = {
|
||||
|
@ -94,14 +94,6 @@ struct mp2629_prop {
|
||||
int shift;
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type mp2629_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_PD_DRP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN
|
||||
};
|
||||
|
||||
static enum power_supply_property mp2629_charger_usb_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
@ -487,8 +479,11 @@ unlock:
|
||||
static const struct power_supply_desc mp2629_usb_desc = {
|
||||
.name = "mp2629_usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = mp2629_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(mp2629_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = mp2629_charger_usb_props,
|
||||
.num_properties = ARRAY_SIZE(mp2629_charger_usb_props),
|
||||
.get_property = mp2629_charger_usb_get_prop,
|
||||
|
@ -154,13 +154,6 @@ enum mt6360_pmu_chg_type {
|
||||
MT6360_CHG_TYPE_MAX,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type mt6360_charger_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
};
|
||||
|
||||
static int mt6360_get_chrdet_ext_stat(struct mt6360_chg_info *mci,
|
||||
bool *pwr_rdy)
|
||||
{
|
||||
@ -574,8 +567,10 @@ static const struct power_supply_desc mt6360_charger_desc = {
|
||||
.get_property = mt6360_charger_get_property,
|
||||
.set_property = mt6360_charger_set_property,
|
||||
.property_is_writeable = mt6360_charger_property_is_writeable,
|
||||
.usb_types = mt6360_charger_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(mt6360_charger_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
static const struct regulator_ops mt6360_chg_otg_ops = {
|
||||
|
@ -624,13 +624,6 @@ static enum power_supply_property mt6370_chg_properties[] = {
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type mt6370_chg_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc mt6370_chg_psy_desc = {
|
||||
.name = "mt6370-charger",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
@ -639,8 +632,10 @@ static const struct power_supply_desc mt6370_chg_psy_desc = {
|
||||
.get_property = mt6370_chg_get_property,
|
||||
.set_property = mt6370_chg_set_property,
|
||||
.property_is_writeable = mt6370_chg_property_is_writeable,
|
||||
.usb_types = mt6370_chg_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(mt6370_chg_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
};
|
||||
|
||||
static const struct regulator_ops mt6370_chg_otg_ops = {
|
||||
|
@ -9,6 +9,7 @@
|
||||
* Modified: 2004, Oct Szabolcs Gyurko
|
||||
*/
|
||||
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/init.h>
|
||||
@ -756,10 +757,10 @@ int power_supply_get_battery_info(struct power_supply *psy,
|
||||
|
||||
for (index = 0; index < len; index++) {
|
||||
struct power_supply_battery_ocv_table *table;
|
||||
char *propname;
|
||||
int i, tab_len, size;
|
||||
|
||||
propname = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d", index);
|
||||
char *propname __free(kfree) = kasprintf(GFP_KERNEL, "ocv-capacity-table-%d",
|
||||
index);
|
||||
if (!propname) {
|
||||
power_supply_put_battery_info(psy, info);
|
||||
err = -ENOMEM;
|
||||
@ -768,13 +769,11 @@ int power_supply_get_battery_info(struct power_supply *psy,
|
||||
list = of_get_property(battery_np, propname, &size);
|
||||
if (!list || !size) {
|
||||
dev_err(&psy->dev, "failed to get %s\n", propname);
|
||||
kfree(propname);
|
||||
power_supply_put_battery_info(psy, info);
|
||||
err = -EINVAL;
|
||||
goto out_put_node;
|
||||
}
|
||||
|
||||
kfree(propname);
|
||||
tab_len = size / (2 * sizeof(__be32));
|
||||
info->ocv_table_size[index] = tab_len;
|
||||
|
||||
@ -1232,11 +1231,7 @@ EXPORT_SYMBOL_GPL(power_supply_set_property);
|
||||
int power_supply_property_is_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
if (atomic_read(&psy->use_cnt) <= 0 ||
|
||||
!psy->desc->property_is_writeable)
|
||||
return -ENODEV;
|
||||
|
||||
return psy->desc->property_is_writeable(psy, psp);
|
||||
return psy->desc->property_is_writeable && psy->desc->property_is_writeable(psy, psp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(power_supply_property_is_writeable);
|
||||
|
||||
@ -1296,7 +1291,7 @@ static int power_supply_read_temp(struct thermal_zone_device *tzd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct thermal_zone_device_ops psy_tzd_ops = {
|
||||
static const struct thermal_zone_device_ops psy_tzd_ops = {
|
||||
.get_temp = power_supply_read_temp,
|
||||
};
|
||||
|
||||
@ -1361,10 +1356,6 @@ __power_supply_register(struct device *parent,
|
||||
pr_warn("%s: Expected proper parent device for '%s'\n",
|
||||
__func__, desc->name);
|
||||
|
||||
if (psy_has_property(desc, POWER_SUPPLY_PROP_USB_TYPE) &&
|
||||
(!desc->usb_types || !desc->num_usb_types))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
psy = kzalloc(sizeof(*psy), GFP_KERNEL);
|
||||
if (!psy)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
@ -318,7 +318,8 @@ static const struct hwmon_channel_info * const power_supply_hwmon_info[] = {
|
||||
HWMON_T_INPUT |
|
||||
HWMON_T_MAX |
|
||||
HWMON_T_MIN |
|
||||
HWMON_T_MIN_ALARM,
|
||||
HWMON_T_MIN_ALARM |
|
||||
HWMON_T_MAX_ALARM,
|
||||
|
||||
HWMON_T_LABEL |
|
||||
HWMON_T_INPUT |
|
||||
|
@ -209,7 +209,7 @@ static struct power_supply_attr power_supply_attrs[] = {
|
||||
POWER_SUPPLY_ATTR(TIME_TO_FULL_NOW),
|
||||
POWER_SUPPLY_ATTR(TIME_TO_FULL_AVG),
|
||||
POWER_SUPPLY_ENUM_ATTR(TYPE),
|
||||
POWER_SUPPLY_ATTR(USB_TYPE),
|
||||
POWER_SUPPLY_ENUM_ATTR(USB_TYPE),
|
||||
POWER_SUPPLY_ENUM_ATTR(SCOPE),
|
||||
POWER_SUPPLY_ATTR(PRECHARGE_CURRENT),
|
||||
POWER_SUPPLY_ATTR(CHARGE_TERM_CURRENT),
|
||||
@ -237,31 +237,28 @@ static enum power_supply_property dev_attr_psp(struct device_attribute *attr)
|
||||
return to_ps_attr(attr) - power_supply_attrs;
|
||||
}
|
||||
|
||||
static ssize_t power_supply_show_usb_type(struct device *dev,
|
||||
const struct power_supply_desc *desc,
|
||||
union power_supply_propval *value,
|
||||
char *buf)
|
||||
static ssize_t power_supply_show_enum_with_available(
|
||||
struct device *dev, const char * const labels[], int label_count,
|
||||
unsigned int available_values, int value, char *buf)
|
||||
{
|
||||
enum power_supply_usb_type usb_type;
|
||||
bool match = false, available, active;
|
||||
ssize_t count = 0;
|
||||
bool match = false;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < desc->num_usb_types; ++i) {
|
||||
usb_type = desc->usb_types[i];
|
||||
for (i = 0; i < label_count; i++) {
|
||||
available = available_values & BIT(i);
|
||||
active = i == value;
|
||||
|
||||
if (value->intval == usb_type) {
|
||||
count += sysfs_emit_at(buf, count, "[%s] ",
|
||||
POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
|
||||
if (available && active) {
|
||||
count += sysfs_emit_at(buf, count, "[%s] ", labels[i]);
|
||||
match = true;
|
||||
} else {
|
||||
count += sysfs_emit_at(buf, count, "%s ",
|
||||
POWER_SUPPLY_USB_TYPE_TEXT[usb_type]);
|
||||
} else if (available) {
|
||||
count += sysfs_emit_at(buf, count, "%s ", labels[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
dev_warn(dev, "driver reporting unsupported connected type\n");
|
||||
dev_warn(dev, "driver reporting unavailable enum value %d\n", value);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -300,8 +297,10 @@ static ssize_t power_supply_show_property(struct device *dev,
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_USB_TYPE:
|
||||
ret = power_supply_show_usb_type(dev, psy->desc,
|
||||
&value, buf);
|
||||
ret = power_supply_show_enum_with_available(
|
||||
dev, POWER_SUPPLY_USB_TYPE_TEXT,
|
||||
ARRAY_SIZE(POWER_SUPPLY_USB_TYPE_TEXT),
|
||||
psy->desc->usb_types, value.intval, buf);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_BEHAVIOUR:
|
||||
ret = power_supply_charge_behaviour_show(dev, psy->desc->charge_behaviours,
|
||||
@ -523,33 +522,10 @@ ssize_t power_supply_charge_behaviour_show(struct device *dev,
|
||||
enum power_supply_charge_behaviour current_behaviour,
|
||||
char *buf)
|
||||
{
|
||||
bool match = false, available, active;
|
||||
ssize_t count = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT); i++) {
|
||||
available = available_behaviours & BIT(i);
|
||||
active = i == current_behaviour;
|
||||
|
||||
if (available && active) {
|
||||
count += sysfs_emit_at(buf, count, "[%s] ",
|
||||
POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]);
|
||||
match = true;
|
||||
} else if (available) {
|
||||
count += sysfs_emit_at(buf, count, "%s ",
|
||||
POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!match) {
|
||||
dev_warn(dev, "driver reporting unsupported charge behaviour\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (count)
|
||||
buf[count - 1] = '\n';
|
||||
|
||||
return count;
|
||||
return power_supply_show_enum_with_available(
|
||||
dev, POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT,
|
||||
ARRAY_SIZE(POWER_SUPPLY_CHARGE_BEHAVIOUR_TEXT),
|
||||
available_behaviours, current_behaviour, buf);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(power_supply_charge_behaviour_show);
|
||||
|
||||
|
@ -786,19 +786,6 @@ static int qcom_battmgr_usb_get_property(struct power_supply *psy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const enum power_supply_usb_type usb_psy_supported_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_ACA,
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_PD_DRP,
|
||||
POWER_SUPPLY_USB_TYPE_PD_PPS,
|
||||
POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID,
|
||||
};
|
||||
|
||||
static const enum power_supply_property sc8280xp_usb_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
@ -809,8 +796,16 @@ static const struct power_supply_desc sc8280xp_usb_psy_desc = {
|
||||
.properties = sc8280xp_usb_props,
|
||||
.num_properties = ARRAY_SIZE(sc8280xp_usb_props),
|
||||
.get_property = qcom_battmgr_usb_get_property,
|
||||
.usb_types = usb_psy_supported_types,
|
||||
.num_usb_types = ARRAY_SIZE(usb_psy_supported_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_ACA) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID),
|
||||
};
|
||||
|
||||
static const enum power_supply_property sm8350_usb_props[] = {
|
||||
@ -829,8 +824,16 @@ static const struct power_supply_desc sm8350_usb_psy_desc = {
|
||||
.properties = sm8350_usb_props,
|
||||
.num_properties = ARRAY_SIZE(sm8350_usb_props),
|
||||
.get_property = qcom_battmgr_usb_get_property,
|
||||
.usb_types = usb_psy_supported_types,
|
||||
.num_usb_types = ARRAY_SIZE(usb_psy_supported_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_ACA) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_DRP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_PPS) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID),
|
||||
};
|
||||
|
||||
static const u8 sm8350_wls_prop_map[] = {
|
||||
|
@ -411,13 +411,6 @@ static enum power_supply_property smb2_properties[] = {
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type smb2_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
};
|
||||
|
||||
static int smb2_get_prop_usb_online(struct smb2_chip *chip, int *val)
|
||||
{
|
||||
unsigned int stat;
|
||||
@ -775,8 +768,10 @@ static irqreturn_t smb2_handle_wdog_bark(int irq, void *data)
|
||||
static const struct power_supply_desc smb2_psy_desc = {
|
||||
.name = "pmi8998_charger",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = smb2_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(smb2_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = smb2_properties,
|
||||
.num_properties = ARRAY_SIZE(smb2_properties),
|
||||
.get_property = smb2_get_property,
|
||||
|
@ -673,11 +673,6 @@ static enum power_supply_property rk817_chg_props[] = {
|
||||
POWER_SUPPLY_PROP_VOLTAGE_AVG,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type rk817_usb_type[] = {
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
static const struct power_supply_desc rk817_bat_desc = {
|
||||
.name = "rk817-battery",
|
||||
.type = POWER_SUPPLY_TYPE_BATTERY,
|
||||
@ -689,8 +684,8 @@ static const struct power_supply_desc rk817_bat_desc = {
|
||||
static const struct power_supply_desc rk817_chg_desc = {
|
||||
.name = "rk817-charger",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = rk817_usb_type,
|
||||
.num_usb_types = ARRAY_SIZE(rk817_usb_type),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = rk817_chg_props,
|
||||
.num_properties = ARRAY_SIZE(rk817_chg_props),
|
||||
.get_property = rk817_chg_get_prop,
|
||||
|
@ -70,13 +70,6 @@ struct rn5t618_power_info {
|
||||
int irq;
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type rn5t618_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN
|
||||
};
|
||||
|
||||
static enum power_supply_property rn5t618_usb_props[] = {
|
||||
/* input current limit is not very accurate */
|
||||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
@ -681,8 +674,10 @@ static const struct power_supply_desc rn5t618_adp_desc = {
|
||||
static const struct power_supply_desc rn5t618_usb_desc = {
|
||||
.name = "rn5t618-usb",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = rn5t618_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(rn5t618_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = rn5t618_usb_props,
|
||||
.num_properties = ARRAY_SIZE(rn5t618_usb_props),
|
||||
.get_property = rn5t618_usb_get_property,
|
||||
|
@ -630,13 +630,6 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const enum power_supply_usb_type rt9467_chg_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
};
|
||||
|
||||
static const enum power_supply_property rt9467_chg_properties[] = {
|
||||
POWER_SUPPLY_PROP_STATUS,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
@ -745,8 +738,6 @@ static int rt9467_psy_set_property(struct power_supply *psy,
|
||||
RT9467_RANGE_IPREC, val->intval);
|
||||
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
|
||||
return rt9467_psy_set_ieoc(data, val->intval);
|
||||
case POWER_SUPPLY_PROP_USB_TYPE:
|
||||
return regmap_field_write(data->rm_field[F_USBCHGEN], val->intval);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -764,7 +755,6 @@ static int rt9467_chg_prop_is_writeable(struct power_supply *psy,
|
||||
case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
|
||||
case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
|
||||
case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
|
||||
case POWER_SUPPLY_PROP_USB_TYPE:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
@ -774,8 +764,10 @@ static int rt9467_chg_prop_is_writeable(struct power_supply *psy,
|
||||
static const struct power_supply_desc rt9467_chg_psy_desc = {
|
||||
.name = "rt9467-charger",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = rt9467_chg_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(rt9467_chg_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.properties = rt9467_chg_properties,
|
||||
.num_properties = ARRAY_SIZE(rt9467_chg_properties),
|
||||
.property_is_writeable = rt9467_chg_prop_is_writeable,
|
||||
|
@ -333,14 +333,6 @@ static enum power_supply_property rt9471_charger_properties[] = {
|
||||
POWER_SUPPLY_PROP_MANUFACTURER,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type rt9471_charger_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID,
|
||||
};
|
||||
|
||||
static int rt9471_charger_property_is_writeable(struct power_supply *psy,
|
||||
enum power_supply_property psp)
|
||||
{
|
||||
@ -726,8 +718,11 @@ static int rt9471_register_psy(struct rt9471_chip *chip)
|
||||
|
||||
desc->name = psy_name;
|
||||
desc->type = POWER_SUPPLY_TYPE_USB;
|
||||
desc->usb_types = rt9471_charger_usb_types;
|
||||
desc->num_usb_types = ARRAY_SIZE(rt9471_charger_usb_types);
|
||||
desc->usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_APPLE_BRICK_ID) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN);
|
||||
desc->properties = rt9471_charger_properties;
|
||||
desc->num_properties = ARRAY_SIZE(rt9471_charger_properties);
|
||||
desc->get_property = rt9471_charger_get_property;
|
||||
|
@ -363,7 +363,7 @@ static int twl4030_charger_update_current(struct twl4030_bci *bci)
|
||||
if (status < 0)
|
||||
return status;
|
||||
cur_reg |= oldreg << 8;
|
||||
if (reg != oldreg) {
|
||||
if (reg != cur_reg) {
|
||||
/* disable write protection for one write access for
|
||||
* BCIIREF */
|
||||
status = twl_i2c_write_u8(TWL_MODULE_MAIN_CHARGE, 0xE7,
|
||||
|
@ -296,22 +296,17 @@ static int ucs1002_set_max_current(struct ucs1002_info *info, u32 val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum power_supply_usb_type ucs1002_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_SDP,
|
||||
POWER_SUPPLY_USB_TYPE_DCP,
|
||||
POWER_SUPPLY_USB_TYPE_CDP,
|
||||
POWER_SUPPLY_USB_TYPE_UNKNOWN,
|
||||
};
|
||||
|
||||
static int ucs1002_set_usb_type(struct ucs1002_info *info, int val)
|
||||
{
|
||||
unsigned int mode;
|
||||
|
||||
if (val < 0 || val >= ARRAY_SIZE(ucs1002_usb_types))
|
||||
return -EINVAL;
|
||||
|
||||
switch (ucs1002_usb_types[val]) {
|
||||
switch (val) {
|
||||
/*
|
||||
* POWER_SUPPLY_USB_TYPE_UNKNOWN == 0, map this to dedicated for
|
||||
* userspace API compatibility with older versions of this driver
|
||||
* which mapped 0 to dedicated.
|
||||
*/
|
||||
case POWER_SUPPLY_USB_TYPE_UNKNOWN:
|
||||
case POWER_SUPPLY_USB_TYPE_PD:
|
||||
mode = V_SET_ACTIVE_MODE_DEDICATED;
|
||||
break;
|
||||
@ -428,8 +423,11 @@ static int ucs1002_property_is_writeable(struct power_supply *psy,
|
||||
static const struct power_supply_desc ucs1002_charger_desc = {
|
||||
.name = "ucs1002",
|
||||
.type = POWER_SUPPLY_TYPE_USB,
|
||||
.usb_types = ucs1002_usb_types,
|
||||
.num_usb_types = ARRAY_SIZE(ucs1002_usb_types),
|
||||
.usb_types = BIT(POWER_SUPPLY_USB_TYPE_SDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_CDP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_DCP) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_UNKNOWN),
|
||||
.get_property = ucs1002_get_property,
|
||||
.set_property = ucs1002_set_property,
|
||||
.property_is_writeable = ucs1002_property_is_writeable,
|
||||
|
@ -1339,12 +1339,6 @@ static void anx7411_get_gpio_irq(struct anx7411_data *ctx)
|
||||
dev_err(dev, "failed to get GPIO IRQ\n");
|
||||
}
|
||||
|
||||
static enum power_supply_usb_type anx7411_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_PD_PPS,
|
||||
};
|
||||
|
||||
static enum power_supply_property anx7411_psy_props[] = {
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
@ -1422,8 +1416,9 @@ static int anx7411_psy_register(struct anx7411_data *ctx)
|
||||
|
||||
psy_desc->name = psy_name;
|
||||
psy_desc->type = POWER_SUPPLY_TYPE_USB;
|
||||
psy_desc->usb_types = anx7411_psy_usb_types;
|
||||
psy_desc->num_usb_types = ARRAY_SIZE(anx7411_psy_usb_types);
|
||||
psy_desc->usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_PPS);
|
||||
psy_desc->properties = anx7411_psy_props;
|
||||
psy_desc->num_properties = ARRAY_SIZE(anx7411_psy_props);
|
||||
|
||||
|
@ -109,12 +109,6 @@ struct rt1719_data {
|
||||
u16 conn_stat;
|
||||
};
|
||||
|
||||
static const enum power_supply_usb_type rt1719_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_PD_PPS
|
||||
};
|
||||
|
||||
static const enum power_supply_property rt1719_psy_properties[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
@ -572,8 +566,9 @@ static int devm_rt1719_psy_register(struct rt1719_data *data)
|
||||
|
||||
data->psy_desc.name = psy_name;
|
||||
data->psy_desc.type = POWER_SUPPLY_TYPE_USB;
|
||||
data->psy_desc.usb_types = rt1719_psy_usb_types;
|
||||
data->psy_desc.num_usb_types = ARRAY_SIZE(rt1719_psy_usb_types);
|
||||
data->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_PPS);
|
||||
data->psy_desc.properties = rt1719_psy_properties;
|
||||
data->psy_desc.num_properties = ARRAY_SIZE(rt1719_psy_properties);
|
||||
data->psy_desc.get_property = rt1719_psy_get_property;
|
||||
|
@ -7483,12 +7483,6 @@ static int tcpm_psy_prop_writeable(struct power_supply *psy,
|
||||
}
|
||||
}
|
||||
|
||||
static enum power_supply_usb_type tcpm_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_PD_PPS,
|
||||
};
|
||||
|
||||
static const char *tcpm_psy_name_prefix = "tcpm-source-psy-";
|
||||
|
||||
static int devm_tcpm_psy_register(struct tcpm_port *port)
|
||||
@ -7509,8 +7503,9 @@ static int devm_tcpm_psy_register(struct tcpm_port *port)
|
||||
port_dev_name);
|
||||
port->psy_desc.name = psy_name;
|
||||
port->psy_desc.type = POWER_SUPPLY_TYPE_USB;
|
||||
port->psy_desc.usb_types = tcpm_psy_usb_types;
|
||||
port->psy_desc.num_usb_types = ARRAY_SIZE(tcpm_psy_usb_types);
|
||||
port->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_PPS);
|
||||
port->psy_desc.properties = tcpm_psy_props;
|
||||
port->psy_desc.num_properties = ARRAY_SIZE(tcpm_psy_props);
|
||||
port->psy_desc.get_property = tcpm_psy_get_prop;
|
||||
|
@ -150,11 +150,6 @@ static enum power_supply_property tps6598x_psy_props[] = {
|
||||
POWER_SUPPLY_PROP_ONLINE,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type tps6598x_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
};
|
||||
|
||||
static const char *tps6598x_psy_name_prefix = "tps6598x-source-psy-";
|
||||
|
||||
/*
|
||||
@ -827,8 +822,8 @@ static int devm_tps6598_psy_register(struct tps6598x *tps)
|
||||
|
||||
tps->psy_desc.name = psy_name;
|
||||
tps->psy_desc.type = POWER_SUPPLY_TYPE_USB;
|
||||
tps->psy_desc.usb_types = tps6598x_psy_usb_types;
|
||||
tps->psy_desc.num_usb_types = ARRAY_SIZE(tps6598x_psy_usb_types);
|
||||
tps->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD);
|
||||
tps->psy_desc.properties = tps6598x_psy_props;
|
||||
tps->psy_desc.num_properties = ARRAY_SIZE(tps6598x_psy_props);
|
||||
tps->psy_desc.get_property = tps6598x_psy_get_prop;
|
||||
|
@ -254,12 +254,6 @@ static int ucsi_psy_get_prop(struct power_supply *psy,
|
||||
}
|
||||
}
|
||||
|
||||
static enum power_supply_usb_type ucsi_psy_usb_types[] = {
|
||||
POWER_SUPPLY_USB_TYPE_C,
|
||||
POWER_SUPPLY_USB_TYPE_PD,
|
||||
POWER_SUPPLY_USB_TYPE_PD_PPS,
|
||||
};
|
||||
|
||||
int ucsi_register_port_psy(struct ucsi_connector *con)
|
||||
{
|
||||
struct power_supply_config psy_cfg = {};
|
||||
@ -276,8 +270,9 @@ int ucsi_register_port_psy(struct ucsi_connector *con)
|
||||
|
||||
con->psy_desc.name = psy_name;
|
||||
con->psy_desc.type = POWER_SUPPLY_TYPE_USB;
|
||||
con->psy_desc.usb_types = ucsi_psy_usb_types;
|
||||
con->psy_desc.num_usb_types = ARRAY_SIZE(ucsi_psy_usb_types);
|
||||
con->psy_desc.usb_types = BIT(POWER_SUPPLY_USB_TYPE_C) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD) |
|
||||
BIT(POWER_SUPPLY_USB_TYPE_PD_PPS);
|
||||
con->psy_desc.properties = ucsi_psy_props;
|
||||
con->psy_desc.num_properties = ARRAY_SIZE(ucsi_psy_props);
|
||||
con->psy_desc.get_property = ucsi_psy_get_prop;
|
||||
|
@ -115,8 +115,16 @@ enum axp20x_variants {
|
||||
#define AXP313A_IRQ_STATE 0x21
|
||||
|
||||
#define AXP717_ON_INDICATE 0x00
|
||||
#define AXP717_PMU_STATUS_2 0x01
|
||||
#define AXP717_BC_DETECT 0x05
|
||||
#define AXP717_PMU_FAULT 0x08
|
||||
#define AXP717_MODULE_EN_CONTROL_1 0x0b
|
||||
#define AXP717_MIN_SYS_V_CONTROL 0x15
|
||||
#define AXP717_INPUT_VOL_LIMIT_CTRL 0x16
|
||||
#define AXP717_INPUT_CUR_LIMIT_CTRL 0x17
|
||||
#define AXP717_MODULE_EN_CONTROL_2 0x19
|
||||
#define AXP717_BOOST_CONTROL 0x1e
|
||||
#define AXP717_VSYS_V_POWEROFF 0x24
|
||||
#define AXP717_IRQ0_EN 0x40
|
||||
#define AXP717_IRQ1_EN 0x41
|
||||
#define AXP717_IRQ2_EN 0x42
|
||||
@ -127,6 +135,9 @@ enum axp20x_variants {
|
||||
#define AXP717_IRQ2_STATE 0x4a
|
||||
#define AXP717_IRQ3_STATE 0x4b
|
||||
#define AXP717_IRQ4_STATE 0x4c
|
||||
#define AXP717_ICC_CHG_SET 0x62
|
||||
#define AXP717_ITERM_CHG_SET 0x63
|
||||
#define AXP717_CV_CHG_SET 0x64
|
||||
#define AXP717_DCDC_OUTPUT_CONTROL 0x80
|
||||
#define AXP717_DCDC1_CONTROL 0x83
|
||||
#define AXP717_DCDC2_CONTROL 0x84
|
||||
@ -147,6 +158,19 @@ enum axp20x_variants {
|
||||
#define AXP717_CLDO3_CONTROL 0x9d
|
||||
#define AXP717_CLDO4_CONTROL 0x9e
|
||||
#define AXP717_CPUSLDO_CONTROL 0x9f
|
||||
#define AXP717_BATT_PERCENT_DATA 0xa4
|
||||
#define AXP717_ADC_CH_EN_CONTROL 0xc0
|
||||
#define AXP717_BATT_V_H 0xc4
|
||||
#define AXP717_BATT_V_L 0xc5
|
||||
#define AXP717_VBUS_V_H 0xc6
|
||||
#define AXP717_VBUS_V_L 0xc7
|
||||
#define AXP717_VSYS_V_H 0xc8
|
||||
#define AXP717_VSYS_V_L 0xc9
|
||||
#define AXP717_BATT_CHRG_I_H 0xca
|
||||
#define AXP717_BATT_CHRG_I_L 0xcb
|
||||
#define AXP717_ADC_DATA_SEL 0xcd
|
||||
#define AXP717_ADC_DATA_H 0xce
|
||||
#define AXP717_ADC_DATA_L 0xcf
|
||||
|
||||
#define AXP806_STARTUP_SRC 0x00
|
||||
#define AXP806_CHIP_ID 0x03
|
||||
|
@ -217,6 +217,10 @@ enum max77693_charger_battery_state {
|
||||
#define CHG_CNFG_01_CHGRSTRT_MASK (0x3 << CHG_CNFG_01_CHGRSTRT_SHIFT)
|
||||
#define CHG_CNFG_01_PQEN_MAKS BIT(CHG_CNFG_01_PQEN_SHIFT)
|
||||
|
||||
/* MAX77693_CHG_REG_CHG_CNFG_02 register */
|
||||
#define CHG_CNFG_02_CC_SHIFT 0
|
||||
#define CHG_CNFG_02_CC_MASK 0x3F
|
||||
|
||||
/* MAX77693_CHG_REG_CHG_CNFG_03 register */
|
||||
#define CHG_CNFG_03_TOITH_SHIFT 0
|
||||
#define CHG_CNFG_03_TOTIME_SHIFT 3
|
||||
@ -244,6 +248,7 @@ enum max77693_charger_battery_state {
|
||||
#define CHG_CNFG_12_VCHGINREG_MASK (0x3 << CHG_CNFG_12_VCHGINREG_SHIFT)
|
||||
|
||||
/* MAX77693 CHG_CNFG_09 Register */
|
||||
#define CHG_CNFG_09_CHGIN_ILIM_SHIFT 0
|
||||
#define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F
|
||||
|
||||
/* MAX77693 CHG_CTRL Register */
|
||||
|
@ -243,8 +243,7 @@ struct power_supply_desc {
|
||||
const char *name;
|
||||
enum power_supply_type type;
|
||||
u8 charge_behaviours;
|
||||
const enum power_supply_usb_type *usb_types;
|
||||
size_t num_usb_types;
|
||||
u32 usb_types;
|
||||
const enum power_supply_property *properties;
|
||||
size_t num_properties;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user