Commit 38525c69 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-v5.10' 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:
   - add wireless type
   - properly document current direction

  Battery/charger driver changes:
   - new fuel-gauge/charger driver for RN5T618/RN5T619
   - new charger driver for BQ25980, BQ25975 and BQ25960
   - bq27xxx-battery: add support for TI bq34z100
   - gpio-charger: convert to GPIO descriptors
   - gpio-charger: add optional support for charge current limiting
   - max17040: add support for max17041, max17043, max17044
   - max17040: add support for max17048, max17049, max17058, max17059
   - smb347-charger: add DT support
   - smb247-charger: add SMB345 and SMB358 support
   - simple-battery: add temperature properties
   - lots of minor fixes, cleanups and DT binding YAML conversions

  Reset drivers:
   - ocelot: Add support for Sparx5"

* tag 'for-v5.10' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power-supply: (81 commits)
  power: reset: POWER_RESET_OCELOT_RESET should depend on Ocelot or Sparx5
  power: supply: bq25980: Fix uninitialized wd_reg_val and overrun
  power: supply: ltc2941: Fix ptr to enum cast
  power: supply: test-power: revise parameter printing to use sprintf
  power: supply: charger-manager: fix incorrect check on charging_duration_ms
  power: supply: max17040: Fix ptr to enum cast
  power: supply: bq25980: Fix uninitialized wd_reg_val
  power: supply: bq25980: remove redundant zero check on ret
  power: reset: ocelot: Add support for Sparx5
  dt-bindings: reset: ocelot: Add Sparx5 support
  power: supply: sbs-battery: keep error code when get_property() fails
  power: supply: bq25980: Add support for the BQ259xx family
  dt-binding: bq25980: Add the bq25980 flash charger
  power: supply: fix spelling mistake "unprecise" -> "imprecise"
  power: supply: test_power: add missing newlines when printing parameters by sysfs
  power: supply: pm2301: drop duplicated i2c_device_id
  power: supply: charger-manager: drop unused charger assignment
  power: supply: rt9455: skip 'struct acpi_device_id' when !CONFIG_ACPI
  power: supply: goldfish: skip 'struct acpi_device_id' when !CONFIG_ACPI
  power: supply: bq25890: skip 'struct acpi_device_id' when !CONFIG_ACPI
  ...
parents f9915b96 7007fab4
...@@ -34,7 +34,7 @@ Description: ...@@ -34,7 +34,7 @@ Description:
Describes the main type of the supply. Describes the main type of the supply.
Access: Read Access: Read
Valid values: "Battery", "UPS", "Mains", "USB" Valid values: "Battery", "UPS", "Mains", "USB", "Wireless"
===== Battery Properties ===== ===== Battery Properties =====
...@@ -108,7 +108,8 @@ Description: ...@@ -108,7 +108,8 @@ Description:
which they average readings to smooth out the reported value. which they average readings to smooth out the reported value.
Access: Read Access: Read
Valid values: Represented in microamps Valid values: Represented in microamps. Negative values are used
for discharging batteries, positive values for charging batteries.
What: /sys/class/power_supply/<supply_name>/current_max What: /sys/class/power_supply/<supply_name>/current_max
Date: October 2010 Date: October 2010
...@@ -127,7 +128,8 @@ Description: ...@@ -127,7 +128,8 @@ Description:
This value is not averaged/smoothed. This value is not averaged/smoothed.
Access: Read Access: Read
Valid values: Represented in microamps Valid values: Represented in microamps. Negative values are used
for discharging batteries, positive values for charging batteries.
What: /sys/class/power_supply/<supply_name>/charge_control_limit What: /sys/class/power_supply/<supply_name>/charge_control_limit
Date: Oct 2012 Date: Oct 2012
......
Microsemi Ocelot reset controller Microsemi Ocelot reset controller
The DEVCPU_GCB:CHIP_REGS have a SOFT_RST register that can be used to reset the The DEVCPU_GCB:CHIP_REGS have a SOFT_RST register that can be used to reset the
SoC MIPS core. SoC core.
The reset registers are both present in the MSCC vcoreiii MIPS and
microchip Sparx5 armv8 SoC's.
Required Properties: Required Properties:
- compatible: "mscc,ocelot-chip-reset" - compatible: "mscc,ocelot-chip-reset" or "microchip,sparx5-chip-reset"
Example: Example:
reset@1070008 { reset@1070008 {
......
Generic reboot mode core map driver
This driver get reboot mode arguments and call the write
interface to store the magic value in special register
or ram. Then the bootloader can read it and take different
action according to the argument stored.
All mode properties are vendor specific, it is a indication to tell
the bootloader what to do when the system reboots, and should be named
as mode-xxx = <magic> (xxx is mode name, magic should be a none-zero value).
For example modes common on Android platform:
- mode-normal: Normal reboot mode, system reboot with command "reboot".
- mode-recovery: Android Recovery mode, it is a mode to format the device or update a new image.
- mode-bootloader: Android fastboot mode, it's a mode to re-flash partitions on the Android based device.
- mode-loader: A bootloader mode, it's a mode used to download image on Rockchip platform,
usually used in development.
Example:
reboot-mode {
mode-normal = <BOOT_NORMAL>;
mode-recovery = <BOOT_RECOVERY>;
mode-bootloader = <BOOT_FASTBOOT>;
mode-loader = <BOOT_BL_DOWNLOAD>;
}
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/power/reset/reboot-mode.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Generic reboot mode core map
maintainers:
- Andy Yan <andy.yan@rock-chips.com>
description: |
This driver get reboot mode arguments and call the write
interface to store the magic value in special register
or ram. Then the bootloader can read it and take different
action according to the argument stored.
All mode properties are vendor specific, it is a indication to tell
the bootloader what to do when the system reboots, and should be named
as mode-xxx = <magic> (xxx is mode name, magic should be a non-zero value).
For example, modes common Android platform are:
- normal: Normal reboot mode, system reboot with command "reboot".
- recovery: Android Recovery mode, it is a mode to format the device or update a new image.
- bootloader: Android fastboot mode, it's a mode to re-flash partitions on the Android based device.
- loader: A bootloader mode, it's a mode used to download image on Rockchip platform,
usually used in development.
properties:
mode-normal:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Default value to set on a reboot if no command was provided.
patternProperties:
"^mode-.*$":
$ref: /schemas/types.yaml#/definitions/uint32
examples:
- |
reboot-mode {
mode-normal = <0>;
mode-recovery = <1>;
mode-bootloader = <2>;
mode-loader = <3>;
};
...
...@@ -82,6 +82,27 @@ properties: ...@@ -82,6 +82,27 @@ properties:
An array containing the temperature in degree Celsius, An array containing the temperature in degree Celsius,
for each of the battery capacity lookup table. for each of the battery capacity lookup table.
operating-range-celsius:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: operating temperature range of a battery
items:
- description: minimum temperature at which battery can operate
- description: maximum temperature at which battery can operate
ambient-celsius:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: safe range of ambient temperature
items:
- description: alert when ambient temperature is lower than this value
- description: alert when ambient temperature is higher than this value
alert-celsius:
$ref: /schemas/types.yaml#/definitions/uint32-array
description: safe range of battery temperature
items:
- description: alert when battery temperature is lower than this value
- description: alert when battery temperature is higher than this value
required: required:
- compatible - compatible
...@@ -130,6 +151,9 @@ examples: ...@@ -130,6 +151,9 @@ examples:
/* table for 10 degree Celsius */ /* table for 10 degree Celsius */
ocv-capacity-table-2 = <4250000 100>, <4200000 95>, <4185000 90>; ocv-capacity-table-2 = <4250000 100>, <4200000 95>, <4185000 90>;
resistance-temp-table = <20 100>, <10 90>, <0 80>, <(-10) 60>; resistance-temp-table = <20 100>, <10 90>, <0 80>, <(-10) 60>;
operating-range-celsius = <(-30) 50>;
ambient-celsius = <(-5) 50>;
alert-celsius = <0 40>;
}; };
charger@11 { charger@11 {
......
...@@ -33,6 +33,10 @@ Optional properties: ...@@ -33,6 +33,10 @@ Optional properties:
- ti,thermal-regulation-threshold: integer, temperature above which the charge - ti,thermal-regulation-threshold: integer, temperature above which the charge
current is lowered, to avoid overheating (in degrees Celsius). If omitted, current is lowered, to avoid overheating (in degrees Celsius). If omitted,
the default setting will be used (120 degrees); the default setting will be used (120 degrees);
- ti,ibatcomp-micro-ohms: integer, value of a resistor in series with
the battery;
- ti,ibatcomp-clamp-microvolt: integer, maximum charging voltage adjustment due
to expected voltage drop on in-series resistor;
Example: Example:
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2020 Texas Instruments Incorporated
%YAML 1.2
---
$id: "http://devicetree.org/schemas/power/supply/bq25980.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: TI BQ25980 Flash Charger
maintainers:
- Dan Murphy <dmurphy@ti.com>
- Ricardo Rivera-Matos <r-rivera-matos@ti.com>
description: |
The BQ25980, BQ25975, and BQ25960 are a series of flash chargers intended
for use in high-power density portable electronics. These inductorless
switching chargers can provide over 97% efficiency by making use of the
switched capacitor architecture.
allOf:
- $ref: power-supply.yaml#
properties:
compatible:
enum:
- ti,bq25980
- ti,bq25975
- ti,bq25960
reg:
maxItems: 1
ti,watchdog-timeout-ms:
description: |
Watchdog timer in milli seconds. 0 disables the watchdog.
default: 0
minimum: 0
maximum: 300000
enum: [ 0, 5000, 10000, 50000, 300000]
ti,sc-ovp-limit-microvolt:
description: |
Minimum input voltage limit in micro volts with a when the charger is in
switch cap mode. 100000 micro volt step.
default: 17800000
minimum: 14000000
maximum: 22000000
ti,sc-ocp-limit-microamp:
description: |
Maximum input current limit in micro amps with a 100000 micro amp step.
minimum: 100000
maximum: 3300000
ti,bypass-ovp-limit-microvolt:
description: |
Minimum input voltage limit in micro volts with a when the charger is in
switch cap mode. 50000 micro volt step.
minimum: 7000000
maximum: 12750000
ti,bypass-ocp-limit-microamp:
description: |
Maximum input current limit in micro amps with a 100000 micro amp step.
minimum: 100000
maximum: 3300000
ti,bypass-enable:
type: boolean
description: Enables bypass mode at boot time
interrupts:
description: |
Indicates that the device state has changed.
monitored-battery:
$ref: /schemas/types.yaml#/definitions/phandle
description: phandle to the battery node being monitored
required:
- compatible
- reg
- monitored-battery
unevaluatedProperties: false
examples:
- |
bat: battery {
compatible = "simple-battery";
constant-charge-current-max-microamp = <4000000>;
constant-charge-voltage-max-microvolt = <8400000>;
precharge-current-microamp = <160000>;
charge-term-current-microamp = <160000>;
};
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0 {
#address-cells = <1>;
#size-cells = <0>;
bq25980: charger@65 {
compatible = "ti,bq25980";
reg = <0x65>;
interrupt-parent = <&gpio1>;
interrupts = <16 IRQ_TYPE_EDGE_FALLING>;
ti,watchdog-timer = <0>;
ti,sc-ocp-limit-microamp = <2000000>;
ti,sc-ovp-limit-microvolt = <17800000>;
monitored-battery = <&bat>;
};
};
...
...@@ -51,6 +51,7 @@ properties: ...@@ -51,6 +51,7 @@ properties:
- ti,bq27621 - ti,bq27621
- ti,bq27z561 - ti,bq27z561
- ti,bq28z610 - ti,bq28z610
- ti,bq34z100
reg: reg:
maxItems: 1 maxItems: 1
......
...@@ -3,24 +3,32 @@ charger-manager bindings ...@@ -3,24 +3,32 @@ charger-manager bindings
Required properties : Required properties :
- compatible : "charger-manager" - compatible : "charger-manager"
- <>-supply : for regulator consumer - <>-supply : for regulator consumer, named according to cm-regulator-name
- cm-num-chargers : number of chargers
- cm-chargers : name of chargers - cm-chargers : name of chargers
- cm-fuel-gauge : name of battery fuel gauge - cm-fuel-gauge : name of battery fuel gauge
- subnode <regulator> : - subnode <regulator> :
- cm-regulator-name : name of charger regulator - cm-regulator-name : name of charger regulator
- subnode <cable> : - subnode <cable> :
- cm-cable-name : name of charger cable - cm-cable-name : name of charger cable - one of USB, USB-HOST,
SDP, DCP, CDP, ACA, FAST-CHARGER, SLOW-CHARGER, WPT,
PD, DOCK, JIG, or MECHANICAL
- cm-cable-extcon : name of extcon dev - cm-cable-extcon : name of extcon dev
(optional) - cm-cable-min : minimum current of cable (optional) - cm-cable-min : minimum current of cable
(optional) - cm-cable-max : maximum current of cable (optional) - cm-cable-max : maximum current of cable
Optional properties : Optional properties :
- cm-name : charger manager's name (default : "battery") - cm-name : charger manager's name (default : "battery")
- cm-poll-mode : polling mode (enum polling_modes) - cm-poll-mode : polling mode - 0 for disabled, 1 for always, 2 for when
- cm-poll-interval : polling interval external power is connected, or 3 for when charging. If not present,
- cm-battery-stat : battery status (enum data_source) then polling is disabled
- cm-fullbatt-* : data for full battery checking - cm-poll-interval : polling interval (in ms)
- cm-battery-stat : battery status - 0 for battery always present, 1 for no
battery, 2 to check presence via fuel gauge, or 3 to check presence
via charger
- cm-fullbatt-vchkdrop-volt : voltage drop (in uV) before restarting charging
- cm-fullbatt-voltage : voltage (in uV) of full battery
- cm-fullbatt-soc : state of charge to consider as full battery
- cm-fullbatt-capacity : capcity (in uAh) to consider as full battery
- cm-thermal-zone : name of external thermometer's thermal zone - cm-thermal-zone : name of external thermometer's thermal zone
- cm-battery-* : threshold battery temperature for charging - cm-battery-* : threshold battery temperature for charging
-cold : critical cold temperature of battery for charging -cold : critical cold temperature of battery for charging
...@@ -29,6 +37,10 @@ Optional properties : ...@@ -29,6 +37,10 @@ Optional properties :
-temp-diff : temperature difference to allow recharging -temp-diff : temperature difference to allow recharging
- cm-dis/charging-max = limits of charging duration - cm-dis/charging-max = limits of charging duration
Deprecated properties:
- cm-num-chargers
- cm-fullbatt-vchkdrop-ms
Example : Example :
charger-manager@0 { charger-manager@0 {
compatible = "charger-manager"; compatible = "charger-manager";
...@@ -39,13 +51,11 @@ Example : ...@@ -39,13 +51,11 @@ Example :
cm-poll-mode = <1>; cm-poll-mode = <1>;
cm-poll-interval = <30000>; cm-poll-interval = <30000>;
cm-fullbatt-vchkdrop-ms = <30000>;
cm-fullbatt-vchkdrop-volt = <150000>; cm-fullbatt-vchkdrop-volt = <150000>;
cm-fullbatt-soc = <100>; cm-fullbatt-soc = <100>;
cm-battery-stat = <3>; cm-battery-stat = <3>;
cm-num-chargers = <3>;
cm-chargers = "charger0", "charger1", "charger2"; cm-chargers = "charger0", "charger1", "charger2";
cm-fuel-gauge = "fuelgauge0"; cm-fuel-gauge = "fuelgauge0";
...@@ -71,7 +81,7 @@ Example : ...@@ -71,7 +81,7 @@ Example :
cm-cable-max = <500000>; cm-cable-max = <500000>;
}; };
cable@1 { cable@1 {
cm-cable-name = "TA"; cm-cable-name = "SDP";
cm-cable-extcon = "extcon-dev.0"; cm-cable-extcon = "extcon-dev.0";
cm-cable-min = <650000>; cm-cable-min = <650000>;
cm-cable-max = <675000>; cm-cable-max = <675000>;
......
...@@ -39,6 +39,25 @@ properties: ...@@ -39,6 +39,25 @@ properties:
maxItems: 1 maxItems: 1
description: GPIO indicating the charging status description: GPIO indicating the charging status
charge-current-limit-gpios:
minItems: 1
maxItems: 32
description: GPIOs used for current limiting
charge-current-limit-mapping:
description: List of tuples with current in uA and a GPIO bitmap (in
this order). The tuples must be provided in descending order of the
current limit.
$ref: /schemas/types.yaml#/definitions/uint32-matrix
items:
items:
- description:
Current limit in uA
- description:
Encoded GPIO setting. Bit 0 represents last GPIO from the
charge-current-limit-gpios property. Bit 1 second to last
GPIO and so on.
required: required:
- compatible - compatible
...@@ -47,6 +66,12 @@ anyOf: ...@@ -47,6 +66,12 @@ anyOf:
- gpios - gpios
- required: - required:
- charge-status-gpios - charge-status-gpios
- required:
- charge-current-limit-gpios
dependencies:
charge-current-limit-gpios: [ charge-current-limit-mapping ]
charge-current-limit-mapping: [ charge-current-limit-gpios ]
additionalProperties: false additionalProperties: false
...@@ -60,4 +85,10 @@ examples: ...@@ -60,4 +85,10 @@ examples:
gpios = <&gpd 28 GPIO_ACTIVE_LOW>; gpios = <&gpd 28 GPIO_ACTIVE_LOW>;
charge-status-gpios = <&gpc 27 GPIO_ACTIVE_LOW>; charge-status-gpios = <&gpc 27 GPIO_ACTIVE_LOW>;
charge-current-limit-gpios = <&gpioA 11 GPIO_ACTIVE_HIGH>,
<&gpioA 12 GPIO_ACTIVE_HIGH>;
charge-current-limit-mapping = <2500000 0x00>, // 2.5 A => both GPIOs low
<700000 0x01>, // 700 mA => GPIO A.12 high
<0 0x02>; // 0 mA => GPIO A.11 high
}; };
* Ingenic JZ47xx battery bindings
Required properties:
- compatible: Must be "ingenic,jz4740-battery".
- io-channels: phandle and IIO specifier pair to the IIO device.
Format described in iio-bindings.txt.
- monitored-battery: phandle to a "simple-battery" compatible node.
The "monitored-battery" property must be a phandle to a node using the format
described in battery.txt, with the following properties being required:
- voltage-min-design-microvolt: Drained battery voltage.
- voltage-max-design-microvolt: Fully charged battery voltage.
Example:
#include <dt-bindings/iio/adc/ingenic,adc.h>
simple_battery: battery {
compatible = "simple-battery";
voltage-min-design-microvolt = <3600000>;
voltage-max-design-microvolt = <4200000>;
};
ingenic_battery {
compatible = "ingenic,jz4740-battery";
io-channels = <&adc INGENIC_ADC_BATTERY>;
io-channel-names = "battery";
monitored-battery = <&simple_battery>;
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
# Copyright 2019-2020 Artur Rojek
%YAML 1.2
---
$id: "http://devicetree.org/schemas/power/supply/ingenic,battery.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Ingenic JZ47xx battery bindings
maintainers:
- Artur Rojek <contact@artur-rojek.eu>
properties:
compatible:
oneOf:
- const: ingenic,jz4740-battery
- items:
- enum:
- ingenic,jz4725b-battery
- ingenic,jz4770-battery
- const: ingenic,jz4740-battery
io-channels:
maxItems: 1
io-channel-names:
const: battery
monitored-battery:
description: >
phandle to a "simple-battery" compatible node.
This property must be a phandle to a node using the format described
in battery.yaml, with the following properties being required:
- voltage-min-design-microvolt: drained battery voltage,
- voltage-max-design-microvolt: fully charged battery voltage.
required:
- compatible
- io-channels
- io-channel-names
- monitored-battery
additionalProperties: false
examples:
- |
#include <dt-bindings/iio/adc/ingenic,adc.h>
simple_battery: battery {
compatible = "simple-battery";
voltage-min-design-microvolt = <3600000>;
voltage-max-design-microvolt = <4200000>;
};
ingenic-battery {
compatible = "ingenic,jz4740-battery";
io-channels = <&adc INGENIC_ADC_BATTERY>;
io-channel-names = "battery";
monitored-battery = <&simple_battery>;
};
...@@ -2,7 +2,9 @@ max17040_battery ...@@ -2,7 +2,9 @@ max17040_battery
~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~
Required properties : Required properties :
- compatible : "maxim,max17040" or "maxim,max77836-battery" - compatible : "maxim,max17040", "maxim,max17041", "maxim,max17043",
"maxim,max17044", "maxim,max17048", "maxim,max17049",
"maxim,max17058", "maxim,max17059" or "maxim,max77836-battery"
- reg: i2c slave address - reg: i2c slave address
Optional properties : Optional properties :
...@@ -11,6 +13,15 @@ Optional properties : ...@@ -11,6 +13,15 @@ Optional properties :
generated. Can be configured from 1 up to 32 generated. Can be configured from 1 up to 32
(%). If skipped the power up default value of (%). If skipped the power up default value of
4 (%) will be used. 4 (%) will be used.
- maxim,double-soc : Certain devices return double the capacity.
Specify this boolean property to divide the
reported value in 2 and thus normalize it.
SOC == State of Charge == Capacity.
- maxim,rcomp : A value to compensate readings for various
battery chemistries and operating temperatures.
max17040,41 have 2 byte rcomp, default to
0x97 0x00. All other devices have one byte
rcomp, default to 0x97.
- interrupts : Interrupt line see Documentation/devicetree/ - interrupts : Interrupt line see Documentation/devicetree/
bindings/interrupt-controller/interrupts.txt bindings/interrupt-controller/interrupts.txt
- wakeup-source : This device has wakeup capabilities. Use this - wakeup-source : This device has wakeup capabilities. Use this
...@@ -31,3 +42,11 @@ Example: ...@@ -31,3 +42,11 @@ Example:
interrupts = <2 IRQ_TYPE_EDGE_FALLING>; interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
wakeup-source; wakeup-source;
}; };
battery-fuel-gauge@36 {
compatible = "maxim,max17048";
reg = <0x36>;
maxim,rcomp = /bits/ 8 <0x56>;
maxim,alert-low-soc-level = <10>;
maxim,double-soc;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: "http://devicetree.org/schemas/power/supply/summit,smb347-charger.yaml#"
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
title: Battery charger driver for SMB345, SMB347 and SMB358
maintainers:
- David Heidelberg <david@ixit.cz>
- Dmitry Osipenko <digetx@gmail.com>
properties:
compatible:
enum:
- summit,smb345
- summit,smb347
- summit,smb358
reg:
maxItems: 1
interrupts:
maxItems: 1
monitored-battery:
description: phandle to the battery node
$ref: /schemas/types.yaml#/definitions/phandle
summit,enable-usb-charging:
type: boolean
description: Enable charging through USB.
summit,enable-otg-charging:
type: boolean
description: Provide power for USB OTG
summit,enable-mains-charging:
type: boolean
description: Enable charging through mains
summit,enable-charge-control:
description: Enable charging control
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # SMB3XX_CHG_ENABLE_SW SW (I2C interface)
- 1 # SMB3XX_CHG_ENABLE_PIN_ACTIVE_LOW Pin control (Active Low)
- 2 # SMB3XX_CHG_ENABLE_PIN_ACTIVE_HIGH Pin control (Active High)
summit,fast-voltage-threshold-microvolt:
description: Voltage threshold to transit to fast charge mode (in uV)
minimum: 2400000
maximum: 3000000
summit,mains-current-limit-microamp:
description: Maximum input current from AC/DC input (in uA)
summit,usb-current-limit-microamp:
description: Maximum input current from USB input (in uA)
summit,charge-current-compensation-microamp:
description: Charge current compensation (in uA)
summit,chip-temperature-threshold-celsius:
description: Chip temperature for thermal regulation in °C.
enum: [100, 110, 120, 130]
summit,soft-compensation-method:
description: Soft temperature limit compensation method
$ref: /schemas/types.yaml#/definitions/uint32
enum:
- 0 # SMB3XX_SOFT_TEMP_COMPENSATE_NONE Compensation none
- 1 # SMB3XX_SOFT_TEMP_COMPENSATE_CURRENT Current compensation
- 2 # SMB3XX_SOFT_TEMP_COMPENSATE_VOLTAGE Voltage compensation
allOf:
- if:
properties:
compatible:
enum:
- summit,smb345
- summit,smb358
then:
properties:
summit,mains-current-limit-microamp:
enum: [ 300000, 500000, 700000, 1000000,
1500000, 1800000, 2000000]
summit,usb-current-limit-microamp:
enum: [ 300000, 500000, 700000, 1000000,
1500000, 1800000, 2000000]
summit,charge-current-compensation-microamp:
enum: [200000, 450000, 600000, 900000]
else:
properties:
summit,mains-current-limit-microamp:
enum: [ 300000, 500000, 700000, 900000, 1200000,
1500000, 1800000, 2000000, 2200000, 2500000]
summit,usb-current-limit-microamp:
enum: [ 300000, 500000, 700000, 900000, 1200000,
1500000, 1800000, 2000000, 2200000, 2500000]
summit,charge-current-compensation-microamp:
enum: [250000, 700000, 900000, 1200000]
required:
- compatible
- reg
anyOf:
- required:
- summit,enable-usb-charging
- required:
- summit,enable-otg-charging
- required:
- summit,enable-mains-charging
additionalProperties: false
examples:
- |
#include <dt-bindings/power/summit,smb347-charger.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
charger@7f {
compatible = "summit,smb347";
reg = <0x7f>;
summit,enable-charge-control = <SMB3XX_CHG_ENABLE_PIN_ACTIVE_HIGH>;
summit,chip-temperature-threshold-celsius = <110>;
summit,mains-current-limit-microamp = <2000000>;
summit,usb-current-limit-microamp = <500000>;
summit,enable-usb-charging;
summit,enable-mains-charging;
monitored-battery = <&battery>;
};
};
battery: battery-cell {
compatible = "simple-battery";
constant-charge-current-max-microamp = <1800000>;
operating-range-celsius = <0 45>;
alert-celsius = <3 42>;
};
...@@ -5231,7 +5231,6 @@ F: kernel/dma/ ...@@ -5231,7 +5231,6 @@ F: kernel/dma/
DMA-BUF HEAPS FRAMEWORK DMA-BUF HEAPS FRAMEWORK
M: Sumit Semwal <sumit.semwal@linaro.org> M: Sumit Semwal <sumit.semwal@linaro.org>
R: Andrew F. Davis <afd@ti.com>
R: Benjamin Gaignard <benjamin.gaignard@linaro.org> R: Benjamin Gaignard <benjamin.gaignard@linaro.org>
R: Liam Mark <lmark@codeaurora.org> R: Liam Mark <lmark@codeaurora.org>
R: Laura Abbott <labbott@redhat.com> R: Laura Abbott <labbott@redhat.com>
...@@ -11605,6 +11604,7 @@ M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com> ...@@ -11605,6 +11604,7 @@ M: Microchip Linux Driver Support <UNGLinuxDriver@microchip.com>
L: linux-mips@vger.kernel.org L: linux-mips@vger.kernel.org
S: Supported S: Supported
F: Documentation/devicetree/bindings/mips/mscc.txt F: Documentation/devicetree/bindings/mips/mscc.txt
F: Documentation/devicetree/bindings/power/reset/ocelot-reset.txt
F: arch/mips/boot/dts/mscc/ F: arch/mips/boot/dts/mscc/
F: arch/mips/configs/generic/board-ocelot.config F: arch/mips/configs/generic/board-ocelot.config
F: arch/mips/generic/board-ocelot.c F: arch/mips/generic/board-ocelot.c
...@@ -17391,7 +17391,7 @@ S: Maintained ...@@ -17391,7 +17391,7 @@ S: Maintained
F: drivers/thermal/ti-soc-thermal/ F: drivers/thermal/ti-soc-thermal/
TI BQ27XXX POWER SUPPLY DRIVER TI BQ27XXX POWER SUPPLY DRIVER
R: Andrew F. Davis <afd@ti.com> R: Dan Murphy <dmurphy@ti.com>
F: drivers/power/supply/bq27xxx_battery.c F: drivers/power/supply/bq27xxx_battery.c
F: drivers/power/supply/bq27xxx_battery_i2c.c F: drivers/power/supply/bq27xxx_battery_i2c.c
F: include/linux/power/bq27xxx_battery.h F: include/linux/power/bq27xxx_battery.h
......
...@@ -369,6 +369,15 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = { ...@@ -369,6 +369,15 @@ static struct pxaficp_platform_data tosa_ficp_platform_data = {
/* /*
* Tosa AC IN * Tosa AC IN
*/ */
static struct gpiod_lookup_table tosa_power_gpiod_table = {
.dev_id = "gpio-charger",
.table = {
GPIO_LOOKUP("gpio-pxa", TOSA_GPIO_AC_IN,
NULL, GPIO_ACTIVE_LOW),
{ },
},
};
static char *tosa_ac_supplied_to[] = { static char *tosa_ac_supplied_to[] = {
"main-battery", "main-battery",
"backup-battery", "backup-battery",
...@@ -378,8 +387,6 @@ static char *tosa_ac_supplied_to[] = { ...@@ -378,8 +387,6 @@ static char *tosa_ac_supplied_to[] = {
static struct gpio_charger_platform_data tosa_power_data = { static struct gpio_charger_platform_data tosa_power_data = {
.name = "charger", .name = "charger",
.type = POWER_SUPPLY_TYPE_MAINS, .type = POWER_SUPPLY_TYPE_MAINS,
.gpio = TOSA_GPIO_AC_IN,
.gpio_active_low = 1,
.supplied_to = tosa_ac_supplied_to, .supplied_to = tosa_ac_supplied_to,
.num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to), .num_supplicants = ARRAY_SIZE(tosa_ac_supplied_to),
}; };
...@@ -951,6 +958,7 @@ static void __init tosa_init(void) ...@@ -951,6 +958,7 @@ static void __init tosa_init(void)
clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL); clk_add_alias("CLK_CK3P6MI", tc6393xb_device.name, "GPIO11_CLK", NULL);
gpiod_add_lookup_table(&tosa_udc_gpiod_table); gpiod_add_lookup_table(&tosa_udc_gpiod_table);
gpiod_add_lookup_table(&tosa_power_gpiod_table);
platform_add_devices(devices, ARRAY_SIZE(devices)); platform_add_devices(devices, ARRAY_SIZE(devices));
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/gpio_keys.h> #include <linux/gpio_keys.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/power/gpio-charger.h> #include <linux/power/gpio-charger.h>
#include <video/sa1100fb.h> #include <video/sa1100fb.h>
...@@ -131,16 +132,23 @@ static struct irda_platform_data collie_ir_data = { ...@@ -131,16 +132,23 @@ static struct irda_platform_data collie_ir_data = {
/* /*
* Collie AC IN * Collie AC IN
*/ */
static struct gpiod_lookup_table collie_power_gpiod_table = {
.dev_id = "gpio-charger",
.table = {
GPIO_LOOKUP("gpio", COLLIE_GPIO_AC_IN,
NULL, GPIO_ACTIVE_HIGH),
{ },
},
};
static char *collie_ac_supplied_to[] = { static char *collie_ac_supplied_to[] = {
"main-battery", "main-battery",
"backup-battery", "backup-battery",
}; };
static struct gpio_charger_platform_data collie_power_data = { static struct gpio_charger_platform_data collie_power_data = {
.name = "charger", .name = "charger",
.type = POWER_SUPPLY_TYPE_MAINS, .type = POWER_SUPPLY_TYPE_MAINS,
.gpio = COLLIE_GPIO_AC_IN,
.supplied_to = collie_ac_supplied_to, .supplied_to = collie_ac_supplied_to,
.num_supplicants = ARRAY_SIZE(collie_ac_supplied_to), .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to),
}; };
...@@ -386,6 +394,8 @@ static void __init collie_init(void) ...@@ -386,6 +394,8 @@ static void __init collie_init(void)
platform_scoop_config = &collie_pcmcia_config; platform_scoop_config = &collie_pcmcia_config;
gpiod_add_lookup_table(&collie_power_gpiod_table);
ret = platform_add_devices(devices, ARRAY_SIZE(devices)); ret = platform_add_devices(devices, ARRAY_SIZE(devices));
if (ret) { if (ret) {
printk(KERN_WARNING "collie: Unable to register LoCoMo device\n"); printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
......
...@@ -129,10 +129,10 @@ config POWER_RESET_QCOM_PON ...@@ -129,10 +129,10 @@ config POWER_RESET_QCOM_PON
config POWER_RESET_OCELOT_RESET config POWER_RESET_OCELOT_RESET
bool "Microsemi Ocelot reset driver" bool "Microsemi Ocelot reset driver"
depends on MSCC_OCELOT || COMPILE_TEST depends on MSCC_OCELOT || ARCH_SPARX5 || COMPILE_TEST
select MFD_SYSCON select MFD_SYSCON
help help
This driver supports restart for Microsemi Ocelot SoC. This driver supports restart for Microsemi Ocelot SoC and similar.
config POWER_RESET_OXNAS config POWER_RESET_OXNAS
bool "OXNAS SoC restart driver" bool "OXNAS SoC restart driver"
......
...@@ -15,15 +15,20 @@ ...@@ -15,15 +15,20 @@
#include <linux/reboot.h> #include <linux/reboot.h>
#include <linux/regmap.h> #include <linux/regmap.h>
struct reset_props {
const char *syscon;
u32 protect_reg;
u32 vcore_protect;
u32 if_si_owner_bit;
};
struct ocelot_reset_context { struct ocelot_reset_context {
void __iomem *base; void __iomem *base;
struct regmap *cpu_ctrl; struct regmap *cpu_ctrl;
const struct reset_props *props;
struct notifier_block restart_handler; struct notifier_block restart_handler;
}; };
#define ICPU_CFG_CPU_SYSTEM_CTRL_RESET 0x20
#define CORE_RST_PROTECT BIT(2)
#define SOFT_CHIP_RST BIT(0) #define SOFT_CHIP_RST BIT(0)
#define ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24 #define ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL 0x24
...@@ -31,7 +36,6 @@ struct ocelot_reset_context { ...@@ -31,7 +36,6 @@ struct ocelot_reset_context {
#define IF_SI_OWNER_SISL 0 #define IF_SI_OWNER_SISL 0
#define IF_SI_OWNER_SIBM 1 #define IF_SI_OWNER_SIBM 1
#define IF_SI_OWNER_SIMC 2 #define IF_SI_OWNER_SIMC 2
#define IF_SI_OWNER_OFFSET 4
static int ocelot_restart_handle(struct notifier_block *this, static int ocelot_restart_handle(struct notifier_block *this,
unsigned long mode, void *cmd) unsigned long mode, void *cmd)
...@@ -39,15 +43,18 @@ static int ocelot_restart_handle(struct notifier_block *this, ...@@ -39,15 +43,18 @@ static int ocelot_restart_handle(struct notifier_block *this,
struct ocelot_reset_context *ctx = container_of(this, struct struct ocelot_reset_context *ctx = container_of(this, struct
ocelot_reset_context, ocelot_reset_context,
restart_handler); restart_handler);
u32 if_si_owner_bit = ctx->props->if_si_owner_bit;
/* Make sure the core is not protected from reset */ /* Make sure the core is not protected from reset */
regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_RESET, regmap_update_bits(ctx->cpu_ctrl, ctx->props->protect_reg,
CORE_RST_PROTECT, 0); ctx->props->vcore_protect, 0);
/* Make the SI back to boot mode */ /* Make the SI back to boot mode */
regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL, regmap_update_bits(ctx->cpu_ctrl, ICPU_CFG_CPU_SYSTEM_CTRL_GENERAL_CTRL,
IF_SI_OWNER_MASK << IF_SI_OWNER_OFFSET, IF_SI_OWNER_MASK << if_si_owner_bit,
IF_SI_OWNER_SIBM << IF_SI_OWNER_OFFSET); IF_SI_OWNER_SIBM << if_si_owner_bit);
pr_emerg("Resetting SoC\n");
writel(SOFT_CHIP_RST, ctx->base); writel(SOFT_CHIP_RST, ctx->base);
...@@ -72,9 +79,13 @@ static int ocelot_reset_probe(struct platform_device *pdev) ...@@ -72,9 +79,13 @@ static int ocelot_reset_probe(struct platform_device *pdev)
if (IS_ERR(ctx->base)) if (IS_ERR(ctx->base))
return PTR_ERR(ctx->base); return PTR_ERR(ctx->base);
ctx->cpu_ctrl = syscon_regmap_lookup_by_compatible("mscc,ocelot-cpu-syscon"); ctx->props = device_get_match_data(dev);
if (IS_ERR(ctx->cpu_ctrl))
ctx->cpu_ctrl = syscon_regmap_lookup_by_compatible(ctx->props->syscon);
if (IS_ERR(ctx->cpu_ctrl)) {
dev_err(dev, "No syscon map: %s\n", ctx->props->syscon);
return PTR_ERR(ctx->cpu_ctrl); return PTR_ERR(ctx->cpu_ctrl);
}
ctx->restart_handler.notifier_call = ocelot_restart_handle; ctx->restart_handler.notifier_call = ocelot_restart_handle;
ctx->restart_handler.priority = 192; ctx->restart_handler.priority = 192;
...@@ -85,9 +96,29 @@ static int ocelot_reset_probe(struct platform_device *pdev) ...@@ -85,9 +96,29 @@ static int ocelot_reset_probe(struct platform_device *pdev)
return err; return err;
} }
static const struct reset_props reset_props_ocelot = {
.syscon = "mscc,ocelot-cpu-syscon",
.protect_reg = 0x20,
.vcore_protect = BIT(2),
.if_si_owner_bit = 4,
};
static const struct reset_props reset_props_sparx5 = {
.syscon = "microchip,sparx5-cpu-syscon",
.protect_reg = 0x84,
.vcore_protect = BIT(10),
.if_si_owner_bit = 6,
};
static const struct of_device_id ocelot_reset_of_match[] = { static const struct of_device_id ocelot_reset_of_match[] = {
{ .compatible = "mscc,ocelot-chip-reset" }, {
{} .compatible = "mscc,ocelot-chip-reset",
.data = &reset_props_ocelot
}, {
.compatible = "microchip,sparx5-chip-reset",
.data = &reset_props_sparx5
},
{ /*sentinel*/ }
}; };
static struct platform_driver ocelot_reset_driver = { static struct platform_driver ocelot_reset_driver = {
......
...@@ -164,7 +164,7 @@ config BATTERY_DS2782 ...@@ -164,7 +164,7 @@ config BATTERY_DS2782
config BATTERY_LEGO_EV3 config BATTERY_LEGO_EV3
tristate "LEGO MINDSTORMS EV3 battery" tristate "LEGO MINDSTORMS EV3 battery"
depends on OF && IIO && GPIOLIB depends on OF && IIO && GPIOLIB && (ARCH_DAVINCI_DA850 || COMPILE_TEST)
help help
Say Y here to enable support for the LEGO MINDSTORMS EV3 battery. Say Y here to enable support for the LEGO MINDSTORMS EV3 battery.
...@@ -367,10 +367,15 @@ config AXP288_FUEL_GAUGE ...@@ -367,10 +367,15 @@ config AXP288_FUEL_GAUGE
config BATTERY_MAX17040 config BATTERY_MAX17040
tristate "Maxim MAX17040 Fuel Gauge" tristate "Maxim MAX17040 Fuel Gauge"
depends on I2C depends on I2C
select REGMAP_I2C
help help
MAX17040 is fuel-gauge systems for lithium-ion (Li+) batteries Maxim models with ModelGauge are fuel-gauge systems for lithium-ion
in handheld and portable equipment. The MAX17040 is configured (Li+) batteries in handheld and portable equipment, including
to operate with a single lithium cell max17040, max17041, max17043, max17044, max17048, max17049, max17058,
max17059. It is also included in some batteries like max77836.
Driver supports reporting SOC (State of Charge, i.e capacity),
voltage and configurable low-SOC wakeup interrupt.
config BATTERY_MAX17042 config BATTERY_MAX17042
tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge" tristate "Maxim MAX17042/17047/17050/8997/8966 Fuel Gauge"
...@@ -631,13 +636,22 @@ config CHARGER_BQ25890 ...@@ -631,13 +636,22 @@ config CHARGER_BQ25890
help help
Say Y to enable support for the TI BQ25890 battery charger. Say Y to enable support for the TI BQ25890 battery charger.
config CHARGER_BQ25980
tristate "TI BQ25980 battery charger driver"
depends on I2C
depends on GPIOLIB || COMPILE_TEST
select REGMAP_I2C
help
Say Y to enable support for the TI BQ25980, BQ25975 and BQ25960
series of fast battery chargers.
config CHARGER_SMB347 config CHARGER_SMB347
tristate "Summit Microelectronics SMB347 Battery Charger" tristate "Summit Microelectronics SMB3XX Battery Charger"
depends on I2C depends on I2C
select REGMAP_I2C select REGMAP_I2C
help help
Say Y to include support for Summit Microelectronics SMB347 Say Y to include support for Summit Microelectronics SMB345,
Battery Charger. SMB347 or SMB358 Battery Charger.
config CHARGER_TPS65090 config CHARGER_TPS65090
tristate "TPS65090 battery charger driver" tristate "TPS65090 battery charger driver"
...@@ -752,4 +766,12 @@ config CHARGER_WILCO ...@@ -752,4 +766,12 @@ config CHARGER_WILCO
information can be found in information can be found in
Documentation/ABI/testing/sysfs-class-power-wilco Documentation/ABI/testing/sysfs-class-power-wilco
config RN5T618_POWER
tristate "RN5T618 charger/fuel gauge support"
depends on MFD_RN5T618
help
Say Y here to have support for RN5T618 PMIC family fuel gauge and charger.
This driver can also be built as a module. If so, the module will be
called rn5t618_power.
endif # POWER_SUPPLY endif # POWER_SUPPLY
...@@ -84,6 +84,7 @@ obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o ...@@ -84,6 +84,7 @@ obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o
obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o
obj-$(CONFIG_CHARGER_BQ2515X) += bq2515x_charger.o obj-$(CONFIG_CHARGER_BQ2515X) += bq2515x_charger.o
obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o
obj-$(CONFIG_CHARGER_BQ25980) += bq25980_charger.o
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o obj-$(CONFIG_CHARGER_TPS65217) += tps65217_charger.o
...@@ -96,3 +97,4 @@ obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o ...@@ -96,3 +97,4 @@ obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o
obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o
obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o
obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o
obj-$(CONFIG_RN5T618_POWER) += rn5t618_power.o
...@@ -653,7 +653,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res) ...@@ -653,7 +653,7 @@ int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res)
/* /*
* negative value for Discharging * negative value for Discharging
* convert 2's compliment into decimal * convert 2's complement into decimal
*/ */
if (high & 0x10) if (high & 0x10)
val = (low | (high << 8) | 0xFFFFE000); val = (low | (high << 8) | 0xFFFFE000);
...@@ -781,7 +781,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work) ...@@ -781,7 +781,7 @@ static void ab8500_fg_acc_cur_work(struct work_struct *work)
if (ret < 0) if (ret < 0)
goto exit; goto exit;
/* Check for sign bit in case of negative value, 2's compliment */ /* Check for sign bit in case of negative value, 2's complement */
if (high & 0x10) if (high & 0x10)
val = (low | (med << 8) | (high << 16) | 0xFFE00000); val = (low | (med << 8) | (high << 16) | 0xFFE00000);
else else
......
...@@ -1152,6 +1152,7 @@ static const struct of_device_id bq24257_of_match[] = { ...@@ -1152,6 +1152,7 @@ static const struct of_device_id bq24257_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, bq24257_of_match); MODULE_DEVICE_TABLE(of, bq24257_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id bq24257_acpi_match[] = { static const struct acpi_device_id bq24257_acpi_match[] = {
{ "BQ242500", BQ24250 }, { "BQ242500", BQ24250 },
{ "BQ242510", BQ24251 }, { "BQ242510", BQ24251 },
...@@ -1159,6 +1160,7 @@ static const struct acpi_device_id bq24257_acpi_match[] = { ...@@ -1159,6 +1160,7 @@ static const struct acpi_device_id bq24257_acpi_match[] = {
{}, {},
}; };
MODULE_DEVICE_TABLE(acpi, bq24257_acpi_match); MODULE_DEVICE_TABLE(acpi, bq24257_acpi_match);
#endif
static struct i2c_driver bq24257_driver = { static struct i2c_driver bq24257_driver = {
.driver = { .driver = {
......
...@@ -168,7 +168,7 @@ enum bq2515x_id { ...@@ -168,7 +168,7 @@ enum bq2515x_id {
* @device_id: value of device_id * @device_id: value of device_id
* @mains_online: boolean value indicating power supply online * @mains_online: boolean value indicating power supply online
* *
* @bq2515x_init_data init_data: charger initialization data structure * @init_data: charger initialization data structure
*/ */
struct bq2515x_device { struct bq2515x_device {
struct power_supply *mains; struct power_supply *mains;
...@@ -188,7 +188,7 @@ struct bq2515x_device { ...@@ -188,7 +188,7 @@ struct bq2515x_device {
struct bq2515x_init_data init_data; struct bq2515x_init_data init_data;
}; };
static struct reg_default bq25150_reg_defaults[] = { static const struct reg_default bq25150_reg_defaults[] = {
{BQ2515X_FLAG0, 0x0}, {BQ2515X_FLAG0, 0x0},
{BQ2515X_FLAG1, 0x0}, {BQ2515X_FLAG1, 0x0},
{BQ2515X_FLAG2, 0x0}, {BQ2515X_FLAG2, 0x0},
...@@ -227,7 +227,7 @@ static struct reg_default bq25150_reg_defaults[] = { ...@@ -227,7 +227,7 @@ static struct reg_default bq25150_reg_defaults[] = {
{BQ2515X_DEVICE_ID, 0x20}, {BQ2515X_DEVICE_ID, 0x20},
}; };
static struct reg_default bq25155_reg_defaults[] = { static const struct reg_default bq25155_reg_defaults[] = {
{BQ2515X_FLAG0, 0x0}, {BQ2515X_FLAG0, 0x0},
{BQ2515X_FLAG1, 0x0}, {BQ2515X_FLAG1, 0x0},
{BQ2515X_FLAG2, 0x0}, {BQ2515X_FLAG2, 0x0},
...@@ -886,14 +886,14 @@ static int bq2515x_battery_get_property(struct power_supply *psy, ...@@ -886,14 +886,14 @@ static int bq2515x_battery_get_property(struct power_supply *psy,
return 0; return 0;
} }
static enum power_supply_property bq2515x_battery_properties[] = { static const enum power_supply_property bq2515x_battery_properties[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW, POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
}; };
static enum power_supply_property bq2515x_mains_properties[] = { static const enum power_supply_property bq2515x_mains_properties[] = {
POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_HEALTH, POWER_SUPPLY_PROP_HEALTH,
...@@ -905,7 +905,7 @@ static enum power_supply_property bq2515x_mains_properties[] = { ...@@ -905,7 +905,7 @@ static enum power_supply_property bq2515x_mains_properties[] = {
POWER_SUPPLY_PROP_PRECHARGE_CURRENT, POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
}; };
static struct power_supply_desc bq2515x_mains_desc = { static const struct power_supply_desc bq2515x_mains_desc = {
.name = "bq2515x-mains", .name = "bq2515x-mains",
.type = POWER_SUPPLY_TYPE_MAINS, .type = POWER_SUPPLY_TYPE_MAINS,
.get_property = bq2515x_mains_get_property, .get_property = bq2515x_mains_get_property,
...@@ -915,7 +915,7 @@ static struct power_supply_desc bq2515x_mains_desc = { ...@@ -915,7 +915,7 @@ static struct power_supply_desc bq2515x_mains_desc = {
.property_is_writeable = bq2515x_power_supply_property_is_writeable, .property_is_writeable = bq2515x_power_supply_property_is_writeable,
}; };
static struct power_supply_desc bq2515x_battery_desc = { static const struct power_supply_desc bq2515x_battery_desc = {
.name = "bq2515x-battery", .name = "bq2515x-battery",
.type = POWER_SUPPLY_TYPE_BATTERY, .type = POWER_SUPPLY_TYPE_BATTERY,
.get_property = bq2515x_battery_get_property, .get_property = bq2515x_battery_get_property,
......
...@@ -83,6 +83,8 @@ struct bq25890_init_data { ...@@ -83,6 +83,8 @@ struct bq25890_init_data {
u8 boostf; /* boost frequency */ u8 boostf; /* boost frequency */
u8 ilim_en; /* enable ILIM pin */ u8 ilim_en; /* enable ILIM pin */
u8 treg; /* thermal regulation threshold */ u8 treg; /* thermal regulation threshold */
u8 rbatcomp; /* IBAT sense resistor value */
u8 vclamp; /* IBAT compensation voltage limit */
}; };
struct bq25890_state { struct bq25890_state {
...@@ -258,6 +260,8 @@ enum bq25890_table_ids { ...@@ -258,6 +260,8 @@ enum bq25890_table_ids {
TBL_VREG, TBL_VREG,
TBL_BOOSTV, TBL_BOOSTV,
TBL_SYSVMIN, TBL_SYSVMIN,
TBL_VBATCOMP,
TBL_RBATCOMP,
/* lookup tables */ /* lookup tables */
TBL_TREG, TBL_TREG,
...@@ -299,6 +303,8 @@ static const union { ...@@ -299,6 +303,8 @@ static const union {
[TBL_VREG] = { .rt = {3840000, 4608000, 16000} }, /* uV */ [TBL_VREG] = { .rt = {3840000, 4608000, 16000} }, /* uV */
[TBL_BOOSTV] = { .rt = {4550000, 5510000, 64000} }, /* uV */ [TBL_BOOSTV] = { .rt = {4550000, 5510000, 64000} }, /* uV */
[TBL_SYSVMIN] = { .rt = {3000000, 3700000, 100000} }, /* uV */ [TBL_SYSVMIN] = { .rt = {3000000, 3700000, 100000} }, /* uV */
[TBL_VBATCOMP] ={ .rt = {0, 224000, 32000} }, /* uV */
[TBL_RBATCOMP] ={ .rt = {0, 140000, 20000} }, /* uOhm */
/* lookup tables */ /* lookup tables */
[TBL_TREG] = { .lt = {bq25890_treg_tbl, BQ25890_TREG_TBL_SIZE} }, [TBL_TREG] = { .lt = {bq25890_treg_tbl, BQ25890_TREG_TBL_SIZE} },
...@@ -648,7 +654,9 @@ static int bq25890_hw_init(struct bq25890_device *bq) ...@@ -648,7 +654,9 @@ static int bq25890_hw_init(struct bq25890_device *bq)
{F_BOOSTI, bq->init_data.boosti}, {F_BOOSTI, bq->init_data.boosti},
{F_BOOSTF, bq->init_data.boostf}, {F_BOOSTF, bq->init_data.boostf},
{F_EN_ILIM, bq->init_data.ilim_en}, {F_EN_ILIM, bq->init_data.ilim_en},
{F_TREG, bq->init_data.treg} {F_TREG, bq->init_data.treg},
{F_BATCMP, bq->init_data.rbatcomp},
{F_VCLAMP, bq->init_data.vclamp},
}; };
ret = bq25890_chip_reset(bq); ret = bq25890_chip_reset(bq);
...@@ -859,11 +867,14 @@ static int bq25890_fw_read_u32_props(struct bq25890_device *bq) ...@@ -859,11 +867,14 @@ static int bq25890_fw_read_u32_props(struct bq25890_device *bq)
{"ti,boost-max-current", false, TBL_BOOSTI, &init->boosti}, {"ti,boost-max-current", false, TBL_BOOSTI, &init->boosti},
/* optional properties */ /* optional properties */
{"ti,thermal-regulation-threshold", true, TBL_TREG, &init->treg} {"ti,thermal-regulation-threshold", true, TBL_TREG, &init->treg},
{"ti,ibatcomp-micro-ohms", true, TBL_RBATCOMP, &init->rbatcomp},
{"ti,ibatcomp-clamp-microvolt", true, TBL_VBATCOMP, &init->vclamp},
}; };
/* initialize data for optional properties */ /* initialize data for optional properties */
init->treg = 3; /* 120 degrees Celsius */ init->treg = 3; /* 120 degrees Celsius */
init->rbatcomp = init->vclamp = 0; /* IBAT compensation disabled */
for (i = 0; i < ARRAY_SIZE(props); i++) { for (i = 0; i < ARRAY_SIZE(props); i++) {
ret = device_property_read_u32(bq->dev, props[i].name, ret = device_property_read_u32(bq->dev, props[i].name,
...@@ -1073,11 +1084,13 @@ static const struct of_device_id bq25890_of_match[] = { ...@@ -1073,11 +1084,13 @@ static const struct of_device_id bq25890_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, bq25890_of_match); MODULE_DEVICE_TABLE(of, bq25890_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id bq25890_acpi_match[] = { static const struct acpi_device_id bq25890_acpi_match[] = {
{"BQ258900", 0}, {"BQ258900", 0},
{}, {},
}; };
MODULE_DEVICE_TABLE(acpi, bq25890_acpi_match); MODULE_DEVICE_TABLE(acpi, bq25890_acpi_match);
#endif
static struct i2c_driver bq25890_driver = { static struct i2c_driver bq25890_driver = {
.driver = { .driver = {
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ */
#ifndef BQ25980_CHARGER_H
#define BQ25980_CHARGER_H
#define BQ25980_MANUFACTURER "Texas Instruments"
#define BQ25980_BATOVP 0x0
#define BQ25980_BATOVP_ALM 0x1
#define BQ25980_BATOCP 0x2
#define BQ25980_BATOCP_ALM 0x3
#define BQ25980_BATUCP_ALM 0x4
#define BQ25980_CHRGR_CTRL_1 0x5
#define BQ25980_BUSOVP 0x6
#define BQ25980_BUSOVP_ALM 0x7
#define BQ25980_BUSOCP 0x8
#define BQ25980_BUSOCP_ALM 0x9
#define BQ25980_TEMP_CONTROL 0xA
#define BQ25980_TDIE_ALM 0xB
#define BQ25980_TSBUS_FLT 0xC
#define BQ25980_TSBAT_FLG 0xD
#define BQ25980_VAC_CONTROL 0xE
#define BQ25980_CHRGR_CTRL_2 0xF
#define BQ25980_CHRGR_CTRL_3 0x10
#define BQ25980_CHRGR_CTRL_4 0x11
#define BQ25980_CHRGR_CTRL_5 0x12
#define BQ25980_STAT1 0x13
#define BQ25980_STAT2 0x14
#define BQ25980_STAT3 0x15
#define BQ25980_STAT4 0x16
#define BQ25980_STAT5 0x17
#define BQ25980_FLAG1 0x18
#define BQ25980_FLAG2 0x19
#define BQ25980_FLAG3 0x1A
#define BQ25980_FLAG4 0x1B
#define BQ25980_FLAG5 0x1C
#define BQ25980_MASK1 0x1D
#define BQ25980_MASK2 0x1E
#define BQ25980_MASK3 0x1F
#define BQ25980_MASK4 0x20
#define BQ25980_MASK5 0x21
#define BQ25980_DEVICE_INFO 0x22
#define BQ25980_ADC_CONTROL1 0x23
#define BQ25980_ADC_CONTROL2 0x24
#define BQ25980_IBUS_ADC_MSB 0x25
#define BQ25980_IBUS_ADC_LSB 0x26
#define BQ25980_VBUS_ADC_MSB 0x27
#define BQ25980_VBUS_ADC_LSB 0x28
#define BQ25980_VAC1_ADC_MSB 0x29
#define BQ25980_VAC1_ADC_LSB 0x2A
#define BQ25980_VAC2_ADC_MSB 0x2B
#define BQ25980_VAC2_ADC_LSB 0x2C
#define BQ25980_VOUT_ADC_MSB 0x2D
#define BQ25980_VOUT_ADC_LSB 0x2E
#define BQ25980_VBAT_ADC_MSB 0x2F
#define BQ25980_VBAT_ADC_LSB 0x30
#define BQ25980_IBAT_ADC_MSB 0x31
#define BQ25980_IBAT_ADC_LSB 0x32
#define BQ25980_TSBUS_ADC_MSB 0x33
#define BQ25980_TSBUS_ADC_LSB 0x34
#define BQ25980_TSBAT_ADC_MSB 0x35
#define BQ25980_TSBAT_ADC_LSB 0x36
#define BQ25980_TDIE_ADC_MSB 0x37
#define BQ25980_TDIE_ADC_LSB 0x38
#define BQ25980_DEGLITCH_TIME 0x39
#define BQ25980_CHRGR_CTRL_6 0x3A
#define BQ25980_BUSOCP_STEP_uA 250000
#define BQ25980_BUSOCP_OFFSET_uA 1000000
#define BQ25980_BUSOCP_DFLT_uA 4250000
#define BQ25975_BUSOCP_DFLT_uA 4250000
#define BQ25960_BUSOCP_DFLT_uA 3250000
#define BQ25980_BUSOCP_MIN_uA 1000000
#define BQ25980_BUSOCP_SC_MAX_uA 5750000
#define BQ25975_BUSOCP_SC_MAX_uA 5750000
#define BQ25960_BUSOCP_SC_MAX_uA 3750000
#define BQ25980_BUSOCP_BYP_MAX_uA 8500000
#define BQ25975_BUSOCP_BYP_MAX_uA 8500000
#define BQ25960_BUSOCP_BYP_MAX_uA 5750000
#define BQ25980_BUSOVP_SC_STEP_uV 100000
#define BQ25975_BUSOVP_SC_STEP_uV 50000
#define BQ25960_BUSOVP_SC_STEP_uV 50000
#define BQ25980_BUSOVP_SC_OFFSET_uV 14000000
#define BQ25975_BUSOVP_SC_OFFSET_uV 7000000
#define BQ25960_BUSOVP_SC_OFFSET_uV 7000000
#define BQ25980_BUSOVP_BYP_STEP_uV 50000
#define BQ25975_BUSOVP_BYP_STEP_uV 25000
#define BQ25960_BUSOVP_BYP_STEP_uV 25000
#define BQ25980_BUSOVP_BYP_OFFSET_uV 7000000
#define BQ25975_BUSOVP_BYP_OFFSET_uV 3500000
#define BQ25960_BUSOVP_BYP_OFFSET_uV 3500000
#define BQ25980_BUSOVP_DFLT_uV 17800000
#define BQ25980_BUSOVP_BYPASS_DFLT_uV 8900000
#define BQ25975_BUSOVP_DFLT_uV 8900000
#define BQ25975_BUSOVP_BYPASS_DFLT_uV 4450000
#define BQ25960_BUSOVP_DFLT_uV 8900000
#define BQ25980_BUSOVP_SC_MIN_uV 14000000
#define BQ25975_BUSOVP_SC_MIN_uV 7000000
#define BQ25960_BUSOVP_SC_MIN_uV 7000000
#define BQ25980_BUSOVP_BYP_MIN_uV 7000000
#define BQ25975_BUSOVP_BYP_MIN_uV 3500000
#define BQ25960_BUSOVP_BYP_MIN_uV 3500000
#define BQ25980_BUSOVP_SC_MAX_uV 22000000
#define BQ25975_BUSOVP_SC_MAX_uV 12750000
#define BQ25960_BUSOVP_SC_MAX_uV 12750000
#define BQ25980_BUSOVP_BYP_MAX_uV 12750000
#define BQ25975_BUSOVP_BYP_MAX_uV 6500000
#define BQ25960_BUSOVP_BYP_MAX_uV 6500000
#define BQ25980_BATOVP_STEP_uV 20000
#define BQ25975_BATOVP_STEP_uV 10000
#define BQ25960_BATOVP_STEP_uV 10000
#define BQ25980_BATOVP_OFFSET_uV 7000000
#define BQ25975_BATOVP_OFFSET_uV 3500000
#define BQ25960_BATOVP_OFFSET_uV 3500000
#define BQ25980_BATOVP_DFLT_uV 14000000
#define BQ25975_BATOVP_DFLT_uV 8900000
#define BQ25960_BATOVP_DFLT_uV 8900000
#define BQ25980_BATOVP_MIN_uV 7000000
#define BQ25975_BATOVP_MIN_uV 3500000
#define BQ25960_BATOVP_MIN_uV 3500000
#define BQ25980_BATOVP_MAX_uV 9540000
#define BQ25975_BATOVP_MAX_uV 4770000
#define BQ25960_BATOVP_MAX_uV 4770000
#define BQ25980_BATOCP_STEP_uA 100000
#define BQ25980_BATOCP_MASK GENMASK(6, 0)
#define BQ25980_BATOCP_DFLT_uA 8100000
#define BQ25960_BATOCP_DFLT_uA 6100000
#define BQ25980_BATOCP_MIN_uA 2000000
#define BQ25980_BATOCP_MAX_uA 11000000
#define BQ25975_BATOCP_MAX_uA 11000000
#define BQ25960_BATOCP_MAX_uA 7000000
#define BQ25980_ENABLE_HIZ 0xff
#define BQ25980_DISABLE_HIZ 0x0
#define BQ25980_EN_BYPASS BIT(3)
#define BQ25980_STAT1_OVP_MASK (BIT(6) | BIT(5) | BIT(0))
#define BQ25980_STAT3_OVP_MASK (BIT(7) | BIT(6))
#define BQ25980_STAT1_OCP_MASK BIT(3)
#define BQ25980_STAT2_OCP_MASK (BIT(6) | BIT(1))
#define BQ25980_STAT4_TFLT_MASK GENMASK(5, 1)
#define BQ25980_WD_STAT BIT(0)
#define BQ25980_PRESENT_MASK GENMASK(4, 2)
#define BQ25980_CHG_EN BIT(4)
#define BQ25980_EN_HIZ BIT(6)
#define BQ25980_ADC_EN BIT(7)
#define BQ25980_ADC_VOLT_STEP_uV 1000
#define BQ25980_ADC_CURR_STEP_uA 1000
#define BQ25980_ADC_POLARITY_BIT BIT(7)
#define BQ25980_WATCHDOG_MASK GENMASK(4, 3)
#define BQ25980_WATCHDOG_DIS BIT(2)
#define BQ25980_WATCHDOG_MAX 300000
#define BQ25980_WATCHDOG_MIN 0
#define BQ25980_NUM_WD_VAL 4
#endif /* BQ25980_CHARGER_H */
// SPDX-License-Identifier: GPL-2.0
/* /*
* BQ27xxx battery driver * BQ27xxx battery driver
* *
...@@ -9,14 +10,6 @@ ...@@ -9,14 +10,6 @@
* *
* Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc. * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
* *
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Datasheets: * Datasheets:
* https://www.ti.com/product/bq27000 * https://www.ti.com/product/bq27000
* https://www.ti.com/product/bq27200 * https://www.ti.com/product/bq27200
...@@ -45,6 +38,7 @@ ...@@ -45,6 +38,7 @@
* https://www.ti.com/product/bq27621-g1 * https://www.ti.com/product/bq27621-g1
* https://www.ti.com/product/bq27z561 * https://www.ti.com/product/bq27z561
* https://www.ti.com/product/bq28z610 * https://www.ti.com/product/bq28z610
* https://www.ti.com/product/bq34z100-g1
*/ */
#include <linux/device.h> #include <linux/device.h>
...@@ -83,7 +77,7 @@ ...@@ -83,7 +77,7 @@
/* BQ27Z561 has different layout for Flags register */ /* BQ27Z561 has different layout for Flags register */
#define BQ27Z561_FLAG_FDC BIT(4) /* Battery fully discharged */ #define BQ27Z561_FLAG_FDC BIT(4) /* Battery fully discharged */
#define BQ27Z561_FLAG_FC BIT(5) /* Battery fully charged */ #define BQ27Z561_FLAG_FC BIT(5) /* Battery fully charged */
#define BQ27Z561_FLAG_DIS_CH BIT(6) /* Battery is discharging */ #define BQ27Z561_FLAG_DIS_CH BIT(6) /* Battery is discharging */
/* control register params */ /* control register params */
...@@ -483,6 +477,26 @@ static u8 ...@@ -483,6 +477,26 @@ static u8
[BQ27XXX_REG_DCAP] = 0x3c, [BQ27XXX_REG_DCAP] = 0x3c,
[BQ27XXX_REG_AP] = 0x22, [BQ27XXX_REG_AP] = 0x22,
BQ27XXX_DM_REG_ROWS, BQ27XXX_DM_REG_ROWS,
},
bq34z100_regs[BQ27XXX_REG_MAX] = {
[BQ27XXX_REG_CTRL] = 0x00,
[BQ27XXX_REG_TEMP] = 0x0c,
[BQ27XXX_REG_INT_TEMP] = 0x2a,
[BQ27XXX_REG_VOLT] = 0x08,
[BQ27XXX_REG_AI] = 0x0a,
[BQ27XXX_REG_FLAGS] = 0x0e,
[BQ27XXX_REG_TTE] = 0x18,
[BQ27XXX_REG_TTF] = 0x1a,
[BQ27XXX_REG_TTES] = 0x1e,
[BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,
[BQ27XXX_REG_NAC] = INVALID_REG_ADDR,
[BQ27XXX_REG_FCC] = 0x06,
[BQ27XXX_REG_CYCT] = 0x2c,
[BQ27XXX_REG_AE] = 0x24,
[BQ27XXX_REG_SOC] = 0x02,
[BQ27XXX_REG_DCAP] = 0x3c,
[BQ27XXX_REG_AP] = 0x22,
BQ27XXX_DM_REG_ROWS,
}; };
static enum power_supply_property bq27000_props[] = { static enum power_supply_property bq27000_props[] = {
...@@ -757,6 +771,27 @@ static enum power_supply_property bq28z610_props[] = { ...@@ -757,6 +771,27 @@ static enum power_supply_property bq28z610_props[] = {
POWER_SUPPLY_PROP_MANUFACTURER, POWER_SUPPLY_PROP_MANUFACTURER,
}; };
static enum power_supply_property bq34z100_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_PRESENT,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_CAPACITY_LEVEL,
POWER_SUPPLY_PROP_TEMP,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
POWER_SUPPLY_PROP_TECHNOLOGY,
POWER_SUPPLY_PROP_CHARGE_FULL,
POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
POWER_SUPPLY_PROP_CYCLE_COUNT,
POWER_SUPPLY_PROP_ENERGY_NOW,
POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_HEALTH,
POWER_SUPPLY_PROP_MANUFACTURER,
};
struct bq27xxx_dm_reg { struct bq27xxx_dm_reg {
u8 subclass_id; u8 subclass_id;
u8 offset; u8 offset;
...@@ -854,13 +889,17 @@ static struct bq27xxx_dm_reg bq27621_dm_regs[] = { ...@@ -854,13 +889,17 @@ static struct bq27xxx_dm_reg bq27621_dm_regs[] = {
#define bq27z561_dm_regs 0 #define bq27z561_dm_regs 0
#define bq28z610_dm_regs 0 #define bq28z610_dm_regs 0
#define bq34z100_dm_regs 0
#define BQ27XXX_O_ZERO 0x00000001
#define BQ27XXX_O_OTDC 0x00000002 /* has OTC/OTD overtemperature flags */ #define BQ27XXX_O_ZERO BIT(0)
#define BQ27XXX_O_UTOT 0x00000004 /* has OT overtemperature flag */ #define BQ27XXX_O_OTDC BIT(1) /* has OTC/OTD overtemperature flags */
#define BQ27XXX_O_CFGUP 0x00000008 #define BQ27XXX_O_UTOT BIT(2) /* has OT overtemperature flag */
#define BQ27XXX_O_RAM 0x00000010 #define BQ27XXX_O_CFGUP BIT(3)
#define BQ27Z561_O_BITS 0x00000020 #define BQ27XXX_O_RAM BIT(4)
#define BQ27Z561_O_BITS BIT(5)
#define BQ27XXX_O_SOC_SI BIT(6) /* SoC is single register */
#define BQ27XXX_O_HAS_CI BIT(7) /* has Capacity Inaccurate flag */
#define BQ27XXX_O_MUL_CHEM BIT(8) /* multiple chemistries supported */
#define BQ27XXX_DATA(ref, key, opt) { \ #define BQ27XXX_DATA(ref, key, opt) { \
.opts = (opt), \ .opts = (opt), \
...@@ -878,8 +917,8 @@ static struct { ...@@ -878,8 +917,8 @@ static struct {
enum power_supply_property *props; enum power_supply_property *props;
size_t props_size; size_t props_size;
} bq27xxx_chip_data[] = { } bq27xxx_chip_data[] = {
[BQ27000] = BQ27XXX_DATA(bq27000, 0 , BQ27XXX_O_ZERO), [BQ27000] = BQ27XXX_DATA(bq27000, 0 , BQ27XXX_O_ZERO | BQ27XXX_O_SOC_SI | BQ27XXX_O_HAS_CI),
[BQ27010] = BQ27XXX_DATA(bq27010, 0 , BQ27XXX_O_ZERO), [BQ27010] = BQ27XXX_DATA(bq27010, 0 , BQ27XXX_O_ZERO | BQ27XXX_O_SOC_SI | BQ27XXX_O_HAS_CI),
[BQ2750X] = BQ27XXX_DATA(bq2750x, 0 , BQ27XXX_O_OTDC), [BQ2750X] = BQ27XXX_DATA(bq2750x, 0 , BQ27XXX_O_OTDC),
[BQ2751X] = BQ27XXX_DATA(bq2751x, 0 , BQ27XXX_O_OTDC), [BQ2751X] = BQ27XXX_DATA(bq2751x, 0 , BQ27XXX_O_OTDC),
[BQ2752X] = BQ27XXX_DATA(bq2752x, 0 , BQ27XXX_O_OTDC), [BQ2752X] = BQ27XXX_DATA(bq2752x, 0 , BQ27XXX_O_OTDC),
...@@ -907,6 +946,8 @@ static struct { ...@@ -907,6 +946,8 @@ static struct {
[BQ27621] = BQ27XXX_DATA(bq27621, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM), [BQ27621] = BQ27XXX_DATA(bq27621, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),
[BQ27Z561] = BQ27XXX_DATA(bq27z561, 0 , BQ27Z561_O_BITS), [BQ27Z561] = BQ27XXX_DATA(bq27z561, 0 , BQ27Z561_O_BITS),
[BQ28Z610] = BQ27XXX_DATA(bq28z610, 0 , BQ27Z561_O_BITS), [BQ28Z610] = BQ27XXX_DATA(bq28z610, 0 , BQ27Z561_O_BITS),
[BQ34Z100] = BQ27XXX_DATA(bq34z100, 0 , BQ27XXX_O_OTDC | BQ27XXX_O_SOC_SI | \
BQ27XXX_O_HAS_CI | BQ27XXX_O_MUL_CHEM),
}; };
static DEFINE_MUTEX(bq27xxx_list_lock); static DEFINE_MUTEX(bq27xxx_list_lock);
...@@ -1426,7 +1467,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di) ...@@ -1426,7 +1467,7 @@ static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)
{ {
int soc; int soc;
if (di->opts & BQ27XXX_O_ZERO) if (di->opts & BQ27XXX_O_SOC_SI)
soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true); soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true);
else else
soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false); soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);
...@@ -1664,7 +1705,7 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di) ...@@ -1664,7 +1705,7 @@ static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di)
void bq27xxx_battery_update(struct bq27xxx_device_info *di) void bq27xxx_battery_update(struct bq27xxx_device_info *di)
{ {
struct bq27xxx_reg_cache cache = {0, }; struct bq27xxx_reg_cache cache = {0, };
bool has_ci_flag = di->opts & BQ27XXX_O_ZERO; bool has_ci_flag = di->opts & BQ27XXX_O_HAS_CI;
bool has_singe_flag = di->opts & BQ27XXX_O_ZERO; bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;
cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag); cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);
...@@ -1772,8 +1813,6 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, ...@@ -1772,8 +1813,6 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
status = POWER_SUPPLY_STATUS_FULL; status = POWER_SUPPLY_STATUS_FULL;
else if (di->cache.flags & BQ27000_FLAG_CHGS) else if (di->cache.flags & BQ27000_FLAG_CHGS)
status = POWER_SUPPLY_STATUS_CHARGING; status = POWER_SUPPLY_STATUS_CHARGING;
else if (power_supply_am_i_supplied(di->bat) > 0)
status = POWER_SUPPLY_STATUS_NOT_CHARGING;
else else
status = POWER_SUPPLY_STATUS_DISCHARGING; status = POWER_SUPPLY_STATUS_DISCHARGING;
} else if (di->opts & BQ27Z561_O_BITS) { } else if (di->opts & BQ27Z561_O_BITS) {
...@@ -1792,6 +1831,10 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di, ...@@ -1792,6 +1831,10 @@ static int bq27xxx_battery_status(struct bq27xxx_device_info *di,
status = POWER_SUPPLY_STATUS_CHARGING; status = POWER_SUPPLY_STATUS_CHARGING;
} }
if ((status == POWER_SUPPLY_STATUS_DISCHARGING) &&
(power_supply_am_i_supplied(di->bat) > 0))
status = POWER_SUPPLY_STATUS_NOT_CHARGING;
val->intval = status; val->intval = status;
return 0; return 0;
...@@ -1916,7 +1959,10 @@ static int bq27xxx_battery_get_property(struct power_supply *psy, ...@@ -1916,7 +1959,10 @@ static int bq27xxx_battery_get_property(struct power_supply *psy,
ret = bq27xxx_simple_value(di->cache.time_to_full, val); ret = bq27xxx_simple_value(di->cache.time_to_full, val);
break; break;
case POWER_SUPPLY_PROP_TECHNOLOGY: case POWER_SUPPLY_PROP_TECHNOLOGY:
val->intval = POWER_SUPPLY_TECHNOLOGY_LION; if (di->opts & BQ27XXX_O_MUL_CHEM)
val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
else
val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
break; break;
case POWER_SUPPLY_PROP_CHARGE_NOW: case POWER_SUPPLY_PROP_CHARGE_NOW:
ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val); ret = bq27xxx_simple_value(bq27xxx_battery_read_nac(di), val);
...@@ -1992,13 +2038,9 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di) ...@@ -1992,13 +2038,9 @@ int bq27xxx_battery_setup(struct bq27xxx_device_info *di)
psy_desc->external_power_changed = bq27xxx_external_power_changed; psy_desc->external_power_changed = bq27xxx_external_power_changed;
di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg); di->bat = power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);
if (IS_ERR(di->bat)) { if (IS_ERR(di->bat))
if (PTR_ERR(di->bat) == -EPROBE_DEFER) return dev_err_probe(di->dev, PTR_ERR(di->bat),
dev_dbg(di->dev, "failed to register battery, deferring probe\n"); "failed to register battery\n");
else
dev_err(di->dev, "failed to register battery\n");
return PTR_ERR(di->bat);
}
bq27xxx_battery_settings(di); bq27xxx_battery_settings(di);
bq27xxx_battery_update(di); bq27xxx_battery_update(di);
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* BQ27xxx battery monitor HDQ/1-wire driver * BQ27xxx battery monitor HDQ/1-wire driver
* *
* Copyright (C) 2007-2017 Texas Instruments Incorporated - https://www.ti.com/ * Copyright (C) 2007-2017 Texas Instruments Incorporated - https://www.ti.com/
* *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
......
// SPDX-License-Identifier: GPL-2.0
/* /*
* BQ27xxx battery monitor I2C driver * BQ27xxx battery monitor I2C driver
* *
* Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
* Andrew F. Davis <afd@ti.com> * Andrew F. Davis <afd@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/ */
#include <linux/i2c.h> #include <linux/i2c.h>
...@@ -255,6 +247,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = { ...@@ -255,6 +247,7 @@ static const struct i2c_device_id bq27xxx_i2c_id_table[] = {
{ "bq27621", BQ27621 }, { "bq27621", BQ27621 },
{ "bq27z561", BQ27Z561 }, { "bq27z561", BQ27Z561 },
{ "bq28z610", BQ28Z610 }, { "bq28z610", BQ28Z610 },
{ "bq34z100", BQ34Z100 },
{}, {},
}; };
MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table); MODULE_DEVICE_TABLE(i2c, bq27xxx_i2c_id_table);
...@@ -290,6 +283,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = { ...@@ -290,6 +283,7 @@ static const struct of_device_id bq27xxx_battery_i2c_of_match_table[] = {
{ .compatible = "ti,bq27621" }, { .compatible = "ti,bq27621" },
{ .compatible = "ti,bq27z561" }, { .compatible = "ti,bq27z561" },
{ .compatible = "ti,bq28z610" }, { .compatible = "ti,bq28z610" },
{ .compatible = "ti,bq34z100" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table); MODULE_DEVICE_TABLE(of, bq27xxx_battery_i2c_of_match_table);
......
This diff is collapsed.
...@@ -747,11 +747,8 @@ static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata) ...@@ -747,11 +747,8 @@ static int cpcap_battery_init_iio(struct cpcap_battery_ddata *ddata)
return 0; return 0;
out_err: out_err:
if (error != -EPROBE_DEFER) return dev_err_probe(ddata->dev, error,
dev_err(ddata->dev, "could not initialize VBUS or ID IIO: %i\n", "could not initialize VBUS or ID IIO\n");
error);
return error;
} }
/* Calibrate coulomb counter */ /* Calibrate coulomb counter */
......
...@@ -160,7 +160,7 @@ static int ds2780_get_voltage(struct ds2780_device_info *dev_info, ...@@ -160,7 +160,7 @@ static int ds2780_get_voltage(struct ds2780_device_info *dev_info,
/* /*
* The voltage value is located in 10 bits across the voltage MSB * The voltage value is located in 10 bits across the voltage MSB
* and LSB registers in two's compliment form * and LSB registers in two's complement form
* Sign bit of the voltage value is in bit 7 of the voltage MSB register * Sign bit of the voltage value is in bit 7 of the voltage MSB register
* Bits 9 - 3 of the voltage value are in bits 6 - 0 of the * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the
* voltage MSB register * voltage MSB register
...@@ -188,7 +188,7 @@ static int ds2780_get_temperature(struct ds2780_device_info *dev_info, ...@@ -188,7 +188,7 @@ static int ds2780_get_temperature(struct ds2780_device_info *dev_info,
/* /*
* The temperature value is located in 10 bits across the temperature * The temperature value is located in 10 bits across the temperature
* MSB and LSB registers in two's compliment form * MSB and LSB registers in two's complement form
* Sign bit of the temperature value is in bit 7 of the temperature * Sign bit of the temperature value is in bit 7 of the temperature
* MSB register * MSB register
* Bits 9 - 3 of the temperature value are in bits 6 - 0 of the * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the
...@@ -241,7 +241,7 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info, ...@@ -241,7 +241,7 @@ static int ds2780_get_current(struct ds2780_device_info *dev_info,
/* /*
* The current value is located in 16 bits across the current MSB * The current value is located in 16 bits across the current MSB
* and LSB registers in two's compliment form * and LSB registers in two's complement form
* Sign bit of the current value is in bit 7 of the current MSB register * Sign bit of the current value is in bit 7 of the current MSB register
* Bits 14 - 8 of the current value are in bits 6 - 0 of the current * Bits 14 - 8 of the current value are in bits 6 - 0 of the current
* MSB register * MSB register
......
...@@ -168,7 +168,7 @@ static int ds2781_get_voltage(struct ds2781_device_info *dev_info, ...@@ -168,7 +168,7 @@ static int ds2781_get_voltage(struct ds2781_device_info *dev_info,
return ret; return ret;
/* /*
* The voltage value is located in 10 bits across the voltage MSB * The voltage value is located in 10 bits across the voltage MSB
* and LSB registers in two's compliment form * and LSB registers in two's complement form
* Sign bit of the voltage value is in bit 7 of the voltage MSB register * Sign bit of the voltage value is in bit 7 of the voltage MSB register
* Bits 9 - 3 of the voltage value are in bits 6 - 0 of the * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the
* voltage MSB register * voltage MSB register
...@@ -197,7 +197,7 @@ static int ds2781_get_temperature(struct ds2781_device_info *dev_info, ...@@ -197,7 +197,7 @@ static int ds2781_get_temperature(struct ds2781_device_info *dev_info,
return ret; return ret;
/* /*
* The temperature value is located in 10 bits across the temperature * The temperature value is located in 10 bits across the temperature
* MSB and LSB registers in two's compliment form * MSB and LSB registers in two's complement form
* Sign bit of the temperature value is in bit 7 of the temperature * Sign bit of the temperature value is in bit 7 of the temperature
* MSB register * MSB register
* Bits 9 - 3 of the temperature value are in bits 6 - 0 of the * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the
...@@ -242,7 +242,7 @@ static int ds2781_get_current(struct ds2781_device_info *dev_info, ...@@ -242,7 +242,7 @@ static int ds2781_get_current(struct ds2781_device_info *dev_info,
/* /*
* The current value is located in 16 bits across the current MSB * The current value is located in 16 bits across the current MSB
* and LSB registers in two's compliment form * and LSB registers in two's complement form
* Sign bit of the current value is in bit 7 of the current MSB register * Sign bit of the current value is in bit 7 of the current MSB register
* Bits 14 - 8 of the current value are in bits 6 - 0 of the current * Bits 14 - 8 of the current value are in bits 6 - 0 of the current
* MSB register * MSB register
......
...@@ -266,11 +266,13 @@ static const struct of_device_id goldfish_battery_of_match[] = { ...@@ -266,11 +266,13 @@ static const struct of_device_id goldfish_battery_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, goldfish_battery_of_match); MODULE_DEVICE_TABLE(of, goldfish_battery_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id goldfish_battery_acpi_match[] = { static const struct acpi_device_id goldfish_battery_acpi_match[] = {
{ "GFSH0001", 0 }, { "GFSH0001", 0 },
{ }, { },
}; };
MODULE_DEVICE_TABLE(acpi, goldfish_battery_acpi_match); MODULE_DEVICE_TABLE(acpi, goldfish_battery_acpi_match);
#endif
static struct platform_driver goldfish_battery_device = { static struct platform_driver goldfish_battery_device = {
.probe = goldfish_battery_probe, .probe = goldfish_battery_probe,
......
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
*/ */
#include <linux/device.h> #include <linux/device.h>
#include <linux/gpio.h> /* For legacy platform data */
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -18,7 +17,13 @@ ...@@ -18,7 +17,13 @@
#include <linux/power/gpio-charger.h> #include <linux/power/gpio-charger.h>
struct gpio_mapping {
u32 limit_ua;
u32 gpiodata;
} __packed;
struct gpio_charger { struct gpio_charger {
struct device *dev;
unsigned int irq; unsigned int irq;
unsigned int charge_status_irq; unsigned int charge_status_irq;
bool wakeup_enabled; bool wakeup_enabled;
...@@ -27,6 +32,11 @@ struct gpio_charger { ...@@ -27,6 +32,11 @@ struct gpio_charger {
struct power_supply_desc charger_desc; struct power_supply_desc charger_desc;
struct gpio_desc *gpiod; struct gpio_desc *gpiod;
struct gpio_desc *charge_status; struct gpio_desc *charge_status;
struct gpio_descs *current_limit_gpios;
struct gpio_mapping *current_limit_map;
u32 current_limit_map_size;
u32 charge_current_limit;
}; };
static irqreturn_t gpio_charger_irq(int irq, void *devid) static irqreturn_t gpio_charger_irq(int irq, void *devid)
...@@ -43,6 +53,35 @@ static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) ...@@ -43,6 +53,35 @@ static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy)
return power_supply_get_drvdata(psy); return power_supply_get_drvdata(psy);
} }
static int set_charge_current_limit(struct gpio_charger *gpio_charger, int val)
{
struct gpio_mapping mapping;
int ndescs = gpio_charger->current_limit_gpios->ndescs;
struct gpio_desc **gpios = gpio_charger->current_limit_gpios->desc;
int i;
if (!gpio_charger->current_limit_map_size)
return -EINVAL;
for (i = 0; i < gpio_charger->current_limit_map_size; i++) {
if (gpio_charger->current_limit_map[i].limit_ua <= val)
break;
}
mapping = gpio_charger->current_limit_map[i];
for (i = 0; i < ndescs; i++) {
bool val = (mapping.gpiodata >> i) & 1;
gpiod_set_value_cansleep(gpios[ndescs-i-1], val);
}
gpio_charger->charge_current_limit = mapping.limit_ua;
dev_dbg(gpio_charger->dev, "set charge current limit to %d (requested: %d)\n",
gpio_charger->charge_current_limit, val);
return 0;
}
static int gpio_charger_get_property(struct power_supply *psy, static int gpio_charger_get_property(struct power_supply *psy,
enum power_supply_property psp, union power_supply_propval *val) enum power_supply_property psp, union power_supply_propval *val)
{ {
...@@ -58,6 +97,24 @@ static int gpio_charger_get_property(struct power_supply *psy, ...@@ -58,6 +97,24 @@ static int gpio_charger_get_property(struct power_supply *psy,
else else
val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
break; break;
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
val->intval = gpio_charger->charge_current_limit;
break;
default:
return -EINVAL;
}
return 0;
}
static int gpio_charger_set_property(struct power_supply *psy,
enum power_supply_property psp, const union power_supply_propval *val)
{
struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy);
switch (psp) {
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
return set_charge_current_limit(gpio_charger, val->intval);
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -65,6 +122,19 @@ static int gpio_charger_get_property(struct power_supply *psy, ...@@ -65,6 +122,19 @@ static int gpio_charger_get_property(struct power_supply *psy,
return 0; return 0;
} }
static int gpio_charger_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
switch (psp) {
case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
return 1;
default:
break;
}
return 0;
}
static enum power_supply_type gpio_charger_get_type(struct device *dev) static enum power_supply_type gpio_charger_get_type(struct device *dev)
{ {
const char *chargetype; const char *chargetype;
...@@ -112,6 +182,61 @@ static int gpio_charger_get_irq(struct device *dev, void *dev_id, ...@@ -112,6 +182,61 @@ static int gpio_charger_get_irq(struct device *dev, void *dev_id,
return irq; return irq;
} }
static int init_charge_current_limit(struct device *dev,
struct gpio_charger *gpio_charger)
{
int i, len;
u32 cur_limit = U32_MAX;
gpio_charger->current_limit_gpios = devm_gpiod_get_array_optional(dev,
"charge-current-limit", GPIOD_OUT_LOW);
if (IS_ERR(gpio_charger->current_limit_gpios)) {
dev_err(dev, "error getting current-limit GPIOs\n");
return PTR_ERR(gpio_charger->current_limit_gpios);
}
if (!gpio_charger->current_limit_gpios)
return 0;
len = device_property_read_u32_array(dev, "charge-current-limit-mapping",
NULL, 0);
if (len < 0)
return len;
if (len == 0 || len % 2) {
dev_err(dev, "invalid charge-current-limit-mapping length\n");
return -EINVAL;
}
gpio_charger->current_limit_map = devm_kmalloc_array(dev,
len / 2, sizeof(*gpio_charger->current_limit_map), GFP_KERNEL);
if (!gpio_charger->current_limit_map)
return -ENOMEM;
gpio_charger->current_limit_map_size = len / 2;
len = device_property_read_u32_array(dev, "charge-current-limit-mapping",
(u32*) gpio_charger->current_limit_map, len);
if (len < 0)
return len;
for (i=0; i < gpio_charger->current_limit_map_size; i++) {
if (gpio_charger->current_limit_map[i].limit_ua > cur_limit) {
dev_err(dev, "charge-current-limit-mapping not sorted by current in descending order\n");
return -EINVAL;
}
cur_limit = gpio_charger->current_limit_map[i].limit_ua;
}
/* default to smallest current limitation for safety reasons */
len = gpio_charger->current_limit_map_size - 1;
set_charge_current_limit(gpio_charger,
gpio_charger->current_limit_map[len].limit_ua);
return 0;
}
/* /*
* The entries will be overwritten by driver's probe routine depending * The entries will be overwritten by driver's probe routine depending
* on the available features. This list ensures, that the array is big * on the available features. This list ensures, that the array is big
...@@ -120,6 +245,7 @@ static int gpio_charger_get_irq(struct device *dev, void *dev_id, ...@@ -120,6 +245,7 @@ static int gpio_charger_get_irq(struct device *dev, void *dev_id,
static enum power_supply_property gpio_charger_properties[] = { static enum power_supply_property gpio_charger_properties[] = {
POWER_SUPPLY_PROP_ONLINE, POWER_SUPPLY_PROP_ONLINE,
POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
}; };
static int gpio_charger_probe(struct platform_device *pdev) static int gpio_charger_probe(struct platform_device *pdev)
...@@ -131,7 +257,6 @@ static int gpio_charger_probe(struct platform_device *pdev) ...@@ -131,7 +257,6 @@ static int gpio_charger_probe(struct platform_device *pdev)
struct power_supply_desc *charger_desc; struct power_supply_desc *charger_desc;
struct gpio_desc *charge_status; struct gpio_desc *charge_status;
int charge_status_irq; int charge_status_irq;
unsigned long flags;
int ret; int ret;
int num_props = 0; int num_props = 0;
...@@ -143,40 +268,17 @@ static int gpio_charger_probe(struct platform_device *pdev) ...@@ -143,40 +268,17 @@ static int gpio_charger_probe(struct platform_device *pdev)
gpio_charger = devm_kzalloc(dev, sizeof(*gpio_charger), GFP_KERNEL); gpio_charger = devm_kzalloc(dev, sizeof(*gpio_charger), GFP_KERNEL);
if (!gpio_charger) if (!gpio_charger)
return -ENOMEM; return -ENOMEM;
gpio_charger->dev = dev;
/* /*
* This will fetch a GPIO descriptor from device tree, ACPI or * This will fetch a GPIO descriptor from device tree, ACPI or
* boardfile descriptor tables. It's good to try this first. * boardfile descriptor tables. It's good to try this first.
*/ */
gpio_charger->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN); gpio_charger->gpiod = devm_gpiod_get_optional(dev, NULL, GPIOD_IN);
if (IS_ERR(gpio_charger->gpiod)) {
/*
* Fallback to legacy platform data method, if no GPIO is specified
* using boardfile descriptor tables.
*/
if (!gpio_charger->gpiod && pdata) {
/* Non-DT: use legacy GPIO numbers */
if (!gpio_is_valid(pdata->gpio)) {
dev_err(dev, "Invalid gpio pin in pdata\n");
return -EINVAL;
}
flags = GPIOF_IN;
if (pdata->gpio_active_low)
flags |= GPIOF_ACTIVE_LOW;
ret = devm_gpio_request_one(dev, pdata->gpio, flags,
dev_name(dev));
if (ret) {
dev_err(dev, "Failed to request gpio pin: %d\n", ret);
return ret;
}
/* Then convert this to gpiod for now */
gpio_charger->gpiod = gpio_to_desc(pdata->gpio);
} else if (IS_ERR(gpio_charger->gpiod)) {
/* Just try again if this happens */ /* Just try again if this happens */
if (PTR_ERR(gpio_charger->gpiod) == -EPROBE_DEFER) return dev_err_probe(dev, PTR_ERR(gpio_charger->gpiod),
return -EPROBE_DEFER; "error getting GPIO descriptor\n");
dev_err(dev, "error getting GPIO descriptor\n");
return PTR_ERR(gpio_charger->gpiod);
} }
if (gpio_charger->gpiod) { if (gpio_charger->gpiod) {
...@@ -193,10 +295,22 @@ static int gpio_charger_probe(struct platform_device *pdev) ...@@ -193,10 +295,22 @@ static int gpio_charger_probe(struct platform_device *pdev)
num_props++; num_props++;
} }
ret = init_charge_current_limit(dev, gpio_charger);
if (ret < 0)
return ret;
if (gpio_charger->current_limit_map) {
gpio_charger_properties[num_props] =
POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX;
num_props++;
}
charger_desc = &gpio_charger->charger_desc; charger_desc = &gpio_charger->charger_desc;
charger_desc->properties = gpio_charger_properties; charger_desc->properties = gpio_charger_properties;
charger_desc->num_properties = num_props; charger_desc->num_properties = num_props;
charger_desc->get_property = gpio_charger_get_property; charger_desc->get_property = gpio_charger_get_property;
charger_desc->set_property = gpio_charger_set_property;
charger_desc->property_is_writeable =
gpio_charger_property_is_writeable;
psy_cfg.of_node = dev->of_node; psy_cfg.of_node = dev->of_node;
psy_cfg.drv_data = gpio_charger; psy_cfg.drv_data = gpio_charger;
......
...@@ -147,11 +147,9 @@ static int ingenic_battery_probe(struct platform_device *pdev) ...@@ -147,11 +147,9 @@ static int ingenic_battery_probe(struct platform_device *pdev)
psy_cfg.of_node = dev->of_node; psy_cfg.of_node = dev->of_node;
bat->battery = devm_power_supply_register(dev, desc, &psy_cfg); bat->battery = devm_power_supply_register(dev, desc, &psy_cfg);
if (IS_ERR(bat->battery)) { if (IS_ERR(bat->battery))
if (PTR_ERR(bat->battery) != -EPROBE_DEFER) return dev_err_probe(dev, PTR_ERR(bat->battery),
dev_err(dev, "Unable to register battery\n"); "Unable to register battery\n");
return PTR_ERR(bat->battery);
}
ret = power_supply_get_battery_info(bat->battery, &bat->info); ret = power_supply_get_battery_info(bat->battery, &bat->info);
if (ret) { if (ret) {
......
...@@ -166,27 +166,21 @@ static int lego_ev3_battery_probe(struct platform_device *pdev) ...@@ -166,27 +166,21 @@ static int lego_ev3_battery_probe(struct platform_device *pdev)
batt->iio_v = devm_iio_channel_get(dev, "voltage"); batt->iio_v = devm_iio_channel_get(dev, "voltage");
err = PTR_ERR_OR_ZERO(batt->iio_v); err = PTR_ERR_OR_ZERO(batt->iio_v);
if (err) { if (err)
if (err != -EPROBE_DEFER) return dev_err_probe(dev, err,
dev_err(dev, "Failed to get voltage iio channel\n"); "Failed to get voltage iio channel\n");
return err;
}
batt->iio_i = devm_iio_channel_get(dev, "current"); batt->iio_i = devm_iio_channel_get(dev, "current");
err = PTR_ERR_OR_ZERO(batt->iio_i); err = PTR_ERR_OR_ZERO(batt->iio_i);
if (err) { if (err)
if (err != -EPROBE_DEFER) return dev_err_probe(dev, err,
dev_err(dev, "Failed to get current iio channel\n"); "Failed to get current iio channel\n");
return err;
}
batt->rechargeable_gpio = devm_gpiod_get(dev, "rechargeable", GPIOD_IN); batt->rechargeable_gpio = devm_gpiod_get(dev, "rechargeable", GPIOD_IN);
err = PTR_ERR_OR_ZERO(batt->rechargeable_gpio); err = PTR_ERR_OR_ZERO(batt->rechargeable_gpio);
if (err) { if (err)
if (err != -EPROBE_DEFER) return dev_err_probe(dev, err,
dev_err(dev, "Failed to get rechargeable gpio\n"); "Failed to get rechargeable gpio\n");
return err;
}
/* /*
* The rechargeable battery indication switch cannot be changed without * The rechargeable battery indication switch cannot be changed without
......
...@@ -473,7 +473,8 @@ static int ltc294x_i2c_probe(struct i2c_client *client, ...@@ -473,7 +473,8 @@ static int ltc294x_i2c_probe(struct i2c_client *client,
np = of_node_get(client->dev.of_node); np = of_node_get(client->dev.of_node);
info->id = (enum ltc294x_id)of_device_get_match_data(&client->dev); info->id = (enum ltc294x_id) (uintptr_t) of_device_get_match_data(
&client->dev);
info->supply_desc.name = np->name; info->supply_desc.name = np->name;
/* r_sense can be negative, when sense+ is connected to the battery /* r_sense can be negative, when sense+ is connected to the battery
......
This diff is collapsed.
...@@ -104,11 +104,6 @@ static int pm2xxx_charger_current_map[] = { ...@@ -104,11 +104,6 @@ static int pm2xxx_charger_current_map[] = {
3000, 3000,
}; };
static const struct i2c_device_id pm2xxx_ident[] = {
{ "pm2301", 0 },
{ }
};
static void set_lpn_pin(struct pm2xxx_charger *pm2) static void set_lpn_pin(struct pm2xxx_charger *pm2)
{ {
if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) { if (!pm2->ac.charger_connected && gpio_is_valid(pm2->lpn_pin)) {
...@@ -396,7 +391,7 @@ static int pm2_int_reg3(void *pm2_data, int val) ...@@ -396,7 +391,7 @@ static int pm2_int_reg3(void *pm2_data, int val)
if (val & (PM2XXX_INT4_ITCHARGINGON)) { if (val & (PM2XXX_INT4_ITCHARGINGON)) {
dev_dbg(pm2->dev , dev_dbg(pm2->dev ,
"chargind operation has started\n"); "charging operation has started\n");
} }
if (val & (PM2XXX_INT4_ITVRESUME)) { if (val & (PM2XXX_INT4_ITVRESUME)) {
......
...@@ -579,6 +579,12 @@ int power_supply_get_battery_info(struct power_supply *psy, ...@@ -579,6 +579,12 @@ int power_supply_get_battery_info(struct power_supply *psy,
info->charge_term_current_ua = -EINVAL; info->charge_term_current_ua = -EINVAL;
info->constant_charge_current_max_ua = -EINVAL; info->constant_charge_current_max_ua = -EINVAL;
info->constant_charge_voltage_max_uv = -EINVAL; info->constant_charge_voltage_max_uv = -EINVAL;
info->temp_ambient_alert_min = INT_MIN;
info->temp_ambient_alert_max = INT_MAX;
info->temp_alert_min = INT_MIN;
info->temp_alert_max = INT_MAX;
info->temp_min = INT_MIN;
info->temp_max = INT_MAX;
info->factory_internal_resistance_uohm = -EINVAL; info->factory_internal_resistance_uohm = -EINVAL;
info->resist_table = NULL; info->resist_table = NULL;
...@@ -639,6 +645,19 @@ int power_supply_get_battery_info(struct power_supply *psy, ...@@ -639,6 +645,19 @@ int power_supply_get_battery_info(struct power_supply *psy,
of_property_read_u32(battery_np, "factory-internal-resistance-micro-ohms", of_property_read_u32(battery_np, "factory-internal-resistance-micro-ohms",
&info->factory_internal_resistance_uohm); &info->factory_internal_resistance_uohm);
of_property_read_u32_index(battery_np, "ambient-celsius",
0, &info->temp_ambient_alert_min);
of_property_read_u32_index(battery_np, "ambient-celsius",
1, &info->temp_ambient_alert_max);
of_property_read_u32_index(battery_np, "alert-celsius",
0, &info->temp_alert_min);
of_property_read_u32_index(battery_np, "alert-celsius",
1, &info->temp_alert_max);
of_property_read_u32_index(battery_np, "operating-range-celsius",
0, &info->temp_min);
of_property_read_u32_index(battery_np, "operating-range-celsius",
1, &info->temp_max);
len = of_property_count_u32_elems(battery_np, "ocv-capacity-celsius"); len = of_property_count_u32_elems(battery_np, "ocv-capacity-celsius");
if (len < 0 && len != -EINVAL) { if (len < 0 && len != -EINVAL) {
err = len; err = len;
......
...@@ -56,6 +56,7 @@ static const char * const POWER_SUPPLY_TYPE_TEXT[] = { ...@@ -56,6 +56,7 @@ static const char * const POWER_SUPPLY_TYPE_TEXT[] = {
[POWER_SUPPLY_TYPE_USB_PD] = "USB_PD", [POWER_SUPPLY_TYPE_USB_PD] = "USB_PD",
[POWER_SUPPLY_TYPE_USB_PD_DRP] = "USB_PD_DRP", [POWER_SUPPLY_TYPE_USB_PD_DRP] = "USB_PD_DRP",
[POWER_SUPPLY_TYPE_APPLE_BRICK_ID] = "BrickID", [POWER_SUPPLY_TYPE_APPLE_BRICK_ID] = "BrickID",
[POWER_SUPPLY_TYPE_WIRELESS] = "Wireless",
}; };
static const char * const POWER_SUPPLY_USB_TYPE_TEXT[] = { static const char * const POWER_SUPPLY_USB_TYPE_TEXT[] = {
......
This diff is collapsed.
...@@ -1731,11 +1731,13 @@ static const struct of_device_id rt9455_of_match[] = { ...@@ -1731,11 +1731,13 @@ static const struct of_device_id rt9455_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, rt9455_of_match); MODULE_DEVICE_TABLE(of, rt9455_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id rt9455_i2c_acpi_match[] = { static const struct acpi_device_id rt9455_i2c_acpi_match[] = {
{ "RT945500", 0 }, { "RT945500", 0 },
{ } { }
}; };
MODULE_DEVICE_TABLE(acpi, rt9455_i2c_acpi_match); MODULE_DEVICE_TABLE(acpi, rt9455_i2c_acpi_match);
#endif
static struct i2c_driver rt9455_driver = { static struct i2c_driver rt9455_driver = {
.probe = rt9455_probe, .probe = rt9455_probe,
......
...@@ -193,7 +193,6 @@ struct sbs_info { ...@@ -193,7 +193,6 @@ struct sbs_info {
struct power_supply *power_supply; struct power_supply *power_supply;
bool is_present; bool is_present;
struct gpio_desc *gpio_detect; struct gpio_desc *gpio_detect;
bool enable_detection;
bool charger_broadcasts; bool charger_broadcasts;
int last_state; int last_state;
int poll_time; int poll_time;
...@@ -480,37 +479,6 @@ static bool sbs_bat_needs_calibration(struct i2c_client *client) ...@@ -480,37 +479,6 @@ static bool sbs_bat_needs_calibration(struct i2c_client *client)
return !!(ret & BIT(7)); return !!(ret & BIT(7));
} }
static int sbs_get_battery_presence_and_health(
struct i2c_client *client, enum power_supply_property psp,
union power_supply_propval *val)
{
int ret;
/* Dummy command; if it succeeds, battery is present. */
ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
if (ret < 0) { /* battery not present*/
if (psp == POWER_SUPPLY_PROP_PRESENT) {
val->intval = 0;
return 0;
}
return ret;
}
if (psp == POWER_SUPPLY_PROP_PRESENT)
val->intval = 1; /* battery present */
else { /* POWER_SUPPLY_PROP_HEALTH */
if (sbs_bat_needs_calibration(client)) {
val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
} else {
/* SBS spec doesn't have a general health command. */
val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
}
}
return 0;
}
static int sbs_get_ti_battery_presence_and_health( static int sbs_get_ti_battery_presence_and_health(
struct i2c_client *client, enum power_supply_property psp, struct i2c_client *client, enum power_supply_property psp,
union power_supply_propval *val) union power_supply_propval *val)
...@@ -569,6 +537,41 @@ static int sbs_get_ti_battery_presence_and_health( ...@@ -569,6 +537,41 @@ static int sbs_get_ti_battery_presence_and_health(
return 0; return 0;
} }
static int sbs_get_battery_presence_and_health(
struct i2c_client *client, enum power_supply_property psp,
union power_supply_propval *val)
{
struct sbs_info *chip = i2c_get_clientdata(client);
int ret;
if (chip->flags & SBS_FLAGS_TI_BQ20ZX5)
return sbs_get_ti_battery_presence_and_health(client, psp, val);
/* Dummy command; if it succeeds, battery is present. */
ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
if (ret < 0) { /* battery not present*/
if (psp == POWER_SUPPLY_PROP_PRESENT) {
val->intval = 0;
return 0;
}
return ret;
}
if (psp == POWER_SUPPLY_PROP_PRESENT)
val->intval = 1; /* battery present */
else { /* POWER_SUPPLY_PROP_HEALTH */
if (sbs_bat_needs_calibration(client)) {
val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
} else {
/* SBS spec doesn't have a general health command. */
val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
}
}
return 0;
}
static int sbs_get_battery_property(struct i2c_client *client, static int sbs_get_battery_property(struct i2c_client *client,
int reg_offset, enum power_supply_property psp, int reg_offset, enum power_supply_property psp,
union power_supply_propval *val) union power_supply_propval *val)
...@@ -871,12 +874,7 @@ static int sbs_get_property(struct power_supply *psy, ...@@ -871,12 +874,7 @@ static int sbs_get_property(struct power_supply *psy,
switch (psp) { switch (psp) {
case POWER_SUPPLY_PROP_PRESENT: case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_HEALTH: case POWER_SUPPLY_PROP_HEALTH:
if (chip->flags & SBS_FLAGS_TI_BQ20ZX5) ret = sbs_get_battery_presence_and_health(client, psp, val);
ret = sbs_get_ti_battery_presence_and_health(client,
psp, val);
else
ret = sbs_get_battery_presence_and_health(client, psp,
val);
/* this can only be true if no gpio is used */ /* this can only be true if no gpio is used */
if (psp == POWER_SUPPLY_PROP_PRESENT) if (psp == POWER_SUPPLY_PROP_PRESENT)
...@@ -967,32 +965,30 @@ static int sbs_get_property(struct power_supply *psy, ...@@ -967,32 +965,30 @@ static int sbs_get_property(struct power_supply *psy,
return -EINVAL; return -EINVAL;
} }
if (!chip->enable_detection) if (!chip->gpio_detect && chip->is_present != (ret >= 0)) {
goto done; bool old_present = chip->is_present;
union power_supply_propval val;
int err = sbs_get_battery_presence_and_health(
client, POWER_SUPPLY_PROP_PRESENT, &val);
if (!chip->gpio_detect && sbs_update_presence(chip, !err && val.intval);
chip->is_present != (ret >= 0)) {
sbs_update_presence(chip, (ret >= 0)); if (old_present != chip->is_present)
power_supply_changed(chip->power_supply); power_supply_changed(chip->power_supply);
} }
done: done:
if (!ret) { if (!ret) {
/* Convert units to match requirements for power supply class */ /* Convert units to match requirements for power supply class */
sbs_unit_adjustment(client, psp, val); sbs_unit_adjustment(client, psp, val);
dev_dbg(&client->dev,
"%s: property = %d, value = %x\n", __func__,
psp, val->intval);
} else if (!chip->is_present) {
/* battery not present, so return NODATA for properties */
ret = -ENODATA;
} }
return ret;
dev_dbg(&client->dev,
"%s: property = %d, value = %x\n", __func__, psp, val->intval);
if (ret && chip->is_present)
return ret;
/* battery not present, so return NODATA for properties */
if (ret)
return -ENODATA;
return 0;
} }
static void sbs_supply_changed(struct sbs_info *chip) static void sbs_supply_changed(struct sbs_info *chip)
...@@ -1098,7 +1094,6 @@ static int sbs_probe(struct i2c_client *client) ...@@ -1098,7 +1094,6 @@ static int sbs_probe(struct i2c_client *client)
chip->flags = (u32)(uintptr_t)device_get_match_data(&client->dev); chip->flags = (u32)(uintptr_t)device_get_match_data(&client->dev);
chip->client = client; chip->client = client;
chip->enable_detection = false;
psy_cfg.of_node = client->dev.of_node; psy_cfg.of_node = client->dev.of_node;
psy_cfg.drv_data = chip; psy_cfg.drv_data = chip;
chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN; chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
...@@ -1159,15 +1154,19 @@ static int sbs_probe(struct i2c_client *client) ...@@ -1159,15 +1154,19 @@ static int sbs_probe(struct i2c_client *client)
* to the battery. * to the battery.
*/ */
if (!(force_load || chip->gpio_detect)) { if (!(force_load || chip->gpio_detect)) {
rc = sbs_read_word_data(client, sbs_data[REG_STATUS].addr); union power_supply_propval val;
if (rc < 0) { rc = sbs_get_battery_presence_and_health(
dev_err(&client->dev, "%s: Failed to get device status\n", client, POWER_SUPPLY_PROP_PRESENT, &val);
__func__); if (rc < 0 || !val.intval) {
dev_err(&client->dev, "Failed to get present status\n");
rc = -ENODEV;
goto exit_psupply; goto exit_psupply;
} }
} }
INIT_DELAYED_WORK(&chip->work, sbs_delayed_work);
chip->power_supply = devm_power_supply_register(&client->dev, sbs_desc, chip->power_supply = devm_power_supply_register(&client->dev, sbs_desc,
&psy_cfg); &psy_cfg);
if (IS_ERR(chip->power_supply)) { if (IS_ERR(chip->power_supply)) {
...@@ -1180,10 +1179,6 @@ static int sbs_probe(struct i2c_client *client) ...@@ -1180,10 +1179,6 @@ static int sbs_probe(struct i2c_client *client)
dev_info(&client->dev, dev_info(&client->dev,
"%s: battery gas gauge device registered\n", client->name); "%s: battery gas gauge device registered\n", client->name);
INIT_DELAYED_WORK(&chip->work, sbs_delayed_work);
chip->enable_detection = true;
return 0; return 0;
exit_psupply: exit_psupply:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: (GPL-2.0-or-later or MIT) */
/*
* Author: David Heidelberg <david@ixit.cz>
*/
#ifndef _DT_BINDINGS_SMB347_CHARGER_H
#define _DT_BINDINGS_SMB347_CHARGER_H
/* Charging compensation method */
#define SMB3XX_SOFT_TEMP_COMPENSATE_NONE 0
#define SMB3XX_SOFT_TEMP_COMPENSATE_CURRENT 1
#define SMB3XX_SOFT_TEMP_COMPENSATE_VOLTAGE 2
/* Charging enable control */
#define SMB3XX_CHG_ENABLE_SW 0
#define SMB3XX_CHG_ENABLE_PIN_ACTIVE_LOW 1
#define SMB3XX_CHG_ENABLE_PIN_ACTIVE_HIGH 2
#endif
...@@ -32,6 +32,7 @@ enum bq27xxx_chip { ...@@ -32,6 +32,7 @@ enum bq27xxx_chip {
BQ27621, BQ27621,
BQ27Z561, BQ27Z561,
BQ28Z610, BQ28Z610,
BQ34Z100,
}; };
struct bq27xxx_device_info; struct bq27xxx_device_info;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment