Add Texas Instruments BQ25703 Charger
Subsystems (5)
cover Add Texas Instruments BQ25703 Charger
From: Chris Morgan <[email protected]>
Add support for the Texas Instruments BQ25703 charger manager. The device integrates a boost converter with the charger manager. This series adds the device as an MFD with separate regulator and power supply drivers. This allows us to manage a circular dependency with a type-c port manager which depends on the regulator for usb-otg but supplies power to the bq25703 charger.
Requesting comments on this series as I want to confirm this is the best way to integrate these functions.
Chris Morgan (5):
dt-bindings: mfd: ti,bq25703a: Add TI BQ25703A Charger
mfd: bq257xx: Add support for BQ25703 core driver
power: supply: bq257xx: Add support for BQ257XX charger manager
regulator: bq257xx: Add bq257xx boost regulator driver
arm64: dts: rockchip: Add USB and charger to Gameforce Ace
.../devicetree/bindings/mfd/ti,bq25703a.yaml | 143 +++ .../dts/rockchip/rk3588s-gameforce-ace.dts | 120 +++ drivers/mfd/Kconfig | 11 + drivers/mfd/Makefile | 1 + drivers/mfd/bq257xx.c | 118 +++ drivers/power/supply/Kconfig | 7 + drivers/power/supply/Makefile | 1 + drivers/power/supply/bq257xx_charger.c | 811 ++++++++++++++++++ drivers/regulator/Kconfig | 8 + drivers/regulator/Makefile | 1 + drivers/regulator/bq257xx-regulator.c | 195 +++++ include/linux/mfd/bq257xx.h | 120 +++ 12 files changed, 1536 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml create mode 100644 drivers/mfd/bq257xx.c create mode 100644 drivers/power/supply/bq257xx_charger.c create mode 100644 drivers/regulator/bq257xx-regulator.c create mode 100644 include/linux/mfd/bq257xx.h
Signature · 1 line
2.34.1
RFC 1/5 dt-bindings: mfd: ti,bq25703a: Add TI BQ25703A Charger
From: Chris Morgan <[email protected]>
Document the Texas instruments BQ25703 series of charger managers/ buck/boost regulators.
--- .../devicetree/bindings/mfd/ti,bq25703a.yaml | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +143 -0
@@ -0,0 +1,143 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,bq25703a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BQ25703 Charger Manager/Buck/Boost Converter + +maintainers: + - Chris Morgan <[email protected]> + +properties: + compatible: + const: ti,bq25703a + + reg: + const: 0x6b + description: I2C slave address + + interrupts: + maxItems: 1 + + power-supplies: + description: + phandle of the power supply that provides input power + $ref: /schemas/types.yaml#/definitions/phandle + + ti,charge-current: + description: + maximum current to apply to charging the battery + minimum: 0 + maximum: 8128000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,current-limit: + description: + maximum total input current allowed + minimum: 50000 + maximum: 6400000 + default: 3250000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,max-charge-voltage: + description: + maximum voltage to apply to charging the battery + minimum: 1024000 + maximum: 19200000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,minimum-sys-voltage: + description: + minimum system voltage while on battery power, with default value + depending based on cell configuration + minimum: 1024000 + maximum: 16128000 + default: + enum: [3584000, 6144000, 9216000, 16128000] + $ref: /schemas/types.yaml#/definitions/uint32 + + regulators: + type: object + additionalProperties: false + description: + Boost converter regulator output of bq257xx + + properties: + "usb-otg-vbus": + type: object + $ref: /schemas/regulator/regulator.yaml + + properties: + regulator-name: true + regulator-min-microamp: + minimum: 0 + maximum: 6350000 + regulator-max-microamp: + minimum: 0 + maximum: 6350000 + regulator-min-microvolt: + minimum: 4480000 + maximum: 20800000 + regulator-max-microvolt: + minimum: 4480000 + maximum: 20800000 + enable-gpios: + description: + The BQ25703 may require both a register write and a GPIO + toggle to enable the boost regulator. + + additionalProperties: true + + required: + - regulator-name + - regulator-min-microamp + - regulator-max-microamp + - regulator-min-microvolt + - regulator-max-microvolt + +additionalProperties: false + +required: + - compatible + - reg + - power-supplies + - ti,charge-current + - ti,current-limit + - ti,max-charge-voltage + - ti,minimum-sys-voltage + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/pinctrl/rockchip.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + bq25703: bq25703@6b { + compatible = "ti,bq25703a"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; + power-supplies = <&fusb302>; + ti,charge-current = <2500000>; + ti,current-limit = <5000000>; + ti,max-charge-voltage = <8750000>; + ti,minimum-sys-voltage = <7400000>; + + regulators { + usb_otg_vbus: usb-otg-vbus { + enable-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + regulator-max-microamp = <960000>; + regulator-max-microvolt = <5088000>; + regulator-min-microamp = <512000>; + regulator-min-microvolt = <4992000>; + regulator-name = "usb_otg_vbus"; + }; + }; + }; + }; + +...
Signature · 1 line
2.34.1
Rob Herring
maintainerRe: [RFC 1/5] dt-bindings: mfd: ti,bq25703a: Add TI BQ25703A Charger
Quoted 17 lines · Chris Morgan
From: Chris Morgan <[email protected]>
Document the Texas instruments BQ25703 series of charger managers/ buck/boost regulators.
Signed-off-by Chris Morgan <[email protected]>--- .../devicetree/bindings/mfd/ti,bq25703a.yaml | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ti,bq25703a.yamlDocumentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +0
-0
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 7
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0@@ -0,0 +1,143 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,bq25703a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BQ25703 Charger Manager/Buck/Boost Converter
BQ25703A?
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 18
Quoted 11 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +11
-0+ +maintainers: + - Chris Morgan <[email protected]> + +properties: + compatible: + const: ti,bq25703a + + reg: + const: 0x6b + description: I2C slave address
Drop description.
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 26
Quoted 8 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +8
-0+ + interrupts: + maxItems: 1 + + power-supplies: + description: + phandle of the power supply that provides input power + $ref: /schemas/types.yaml#/definitions/phandle
Already has a type. You need a reference to power-supply.yaml at the top level and 'maxItems: 1' here.
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 33
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0+ + ti,charge-current: + description: + maximum current to apply to charging the battery + minimum: 0 + maximum: 8128000 + $ref: /schemas/types.yaml#/definitions/uint32
I guess this is copied from other TI parts, but really this should move to a property with a unit suffix. Or these shared properties moved to a shared schema so we aren't redefining the type multiple times.
Same for the others here.
Quoted 21 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +21
-0+ + ti,current-limit: + description: + maximum total input current allowed + minimum: 50000 + maximum: 6400000 + default: 3250000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,max-charge-voltage: + description: + maximum voltage to apply to charging the battery + minimum: 1024000 + maximum: 19200000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,minimum-sys-voltage: + description: + minimum system voltage while on battery power, with default value + depending based on cell configuration + minimum: 1024000
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 64
Quoted 10 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +10
-0+ maximum: 16128000 + default: + enum: [3584000, 6144000, 9216000, 16128000] + $ref: /schemas/types.yaml#/definitions/uint32 + + regulators: + type: object + additionalProperties: false + description: + Boost converter regulator output of bq257xx
Doesn't this apply to "usb-otg-vbus"?
Really, only one regulator, so you don't need a container node.
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 67
Quoted 3 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +3
-0+ + properties: + "usb-otg-vbus":
Don't need quotes.
Quoted 13 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +13
-0+ type: object + $ref: /schemas/regulator/regulator.yaml + + properties: + regulator-name: true + regulator-min-microamp: + minimum: 0 + maximum: 6350000 + regulator-max-microamp: + minimum: 0 + maximum: 6350000 + regulator-min-microvolt: + minimum: 4480000
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 90
Quoted 10 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +10
-0+ maximum: 20800000 + regulator-max-microvolt: + minimum: 4480000 + maximum: 20800000 + enable-gpios: + description: + The BQ25703 may require both a register write and a GPIO + toggle to enable the boost regulator. + + additionalProperties: true
Nope.
Quoted 19 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +19
-0+ + required: + - regulator-name + - regulator-min-microamp + - regulator-max-microamp + - regulator-min-microvolt + - regulator-max-microvolt + +additionalProperties: false + +required: + - compatible + - reg + - power-supplies + - ti,charge-current + - ti,current-limit + - ti,max-charge-voltage + - ti,minimum-sys-voltage +
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 119
Quoted 10 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +10
-0+examples: + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/pinctrl/rockchip.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + bq25703: bq25703@6b {
charger@6b
Quoted 27 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +24
-0+ compatible = "ti,bq25703a"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; + power-supplies = <&fusb302>; + ti,charge-current = <2500000>; + ti,current-limit = <5000000>; + ti,max-charge-voltage = <8750000>; + ti,minimum-sys-voltage = <7400000>; + + regulators { + usb_otg_vbus: usb-otg-vbus { + enable-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + regulator-max-microamp = <960000>; + regulator-max-microvolt = <5088000>; + regulator-min-microamp = <512000>; + regulator-min-microvolt = <4992000>; + regulator-name = "usb_otg_vbus"; + }; + }; + }; + }; + +...Signature · 1 line
2.34.1
Re: [RFC 1/5] dt-bindings: mfd: ti,bq25703a: Add TI BQ25703A Charger
Quoted 12 lines · Rob Herring
Quoted 11 lines · Chris Morgan
From: Chris Morgan <[email protected]>
Document the Texas instruments BQ25703 series of charger managers/ buck/boost regulators.
Signed-off-by Chris Morgan <[email protected]>--- .../devicetree/bindings/mfd/ti,bq25703a.yaml | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml
Quoted 15 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 7
Quoted 13 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0@@ -0,0 +1,143 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,bq25703a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BQ25703 Charger Manager/Buck/Boost ConverterBQ25703A?
I'm not entirely sure on the nomenclature. I know for sure I have a BQ25703A in my device, but I don't know if the A is important or not. I'll just drop it until I know for sure to alleviate confusion.
Quoted 14 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 18
Quoted 12 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +11
-0+ +maintainers: + - Chris Morgan <[email protected]> + +properties: + compatible: + const: ti,bq25703a + + reg: + const: 0x6b + description: I2C slave addressDrop description.
Acknowledged.
Quoted 12 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 26
Quoted 9 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +8
-0+ + interrupts: + maxItems: 1 + + power-supplies: + description: + phandle of the power supply that provides input power + $ref: /schemas/types.yaml#/definitions/phandleAlready has a type. You need a reference to
power-supply.yamlat the top level and 'maxItems: 1' here.
Gotcha, thank you.
Quoted 9 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 33
Quoted 8 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0+ + ti,charge-current: + description: + maximum current to apply to charging the battery + minimum: 0 + maximum: 8128000 + $ref: /schemas/types.yaml#/definitions/uint32
Quoted 5 lines
I guess this is copied from other TI parts, but really this should move to a property with a unit suffix. Or these shared properties moved to a shared schema so we aren't redefining the type multiple times.
Same for the others here.
Correct, I tried to reuse the same TI specific properties. I suppose I could also eliminate ti,charge-current and ti,max-charge-voltage, and then just require a phandle to a simple-battery node which contains those two values in a vendor independent form. What do you think?
ti,current-limit and ti,minimum-system-voltage though are other possible questions I have. Basically I could also create a vsys regulator that represents the vsys coming off this device too (I currently omit this entirely). This regulator wouldn't be programable but would report the existing input current and input voltage for the system, which in my case I'm pretty sure is stepped down to 5v or less and then fed into an RK806 PMIC (I lack the schematics so I don't know for sure). Of course if I did that then I'd have a valid reason to add a "regulators" node since I'd have more than one regulator.
Quoted 35 lines
Quoted 22 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +21
-0+ + ti,current-limit: + description: + maximum total input current allowed + minimum: 50000 + maximum: 6400000 + default: 3250000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,max-charge-voltage: + description: + maximum voltage to apply to charging the battery + minimum: 1024000 + maximum: 19200000 + $ref: /schemas/types.yaml#/definitions/uint32 + + ti,minimum-sys-voltage: + description: + minimum system voltage while on battery power, with default value + depending based on cell configuration + minimum: 1024000Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 64
Quoted 10 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +10
-0+ maximum: 16128000 + default: + enum: [3584000, 6144000, 9216000, 16128000] + $ref: /schemas/types.yaml#/definitions/uint32 + + regulators: + type: object + additionalProperties: false + description: + Boost converter regulator output of bq257xxDoesn't this apply to "usb-otg-vbus"?
Quoted 2 lines
Really, only one regulator, so you don't need a container node.
It does, that's a mistake on my part. And see above; I could add a regulator for the vsys (even though you wouldn't be able to set the voltage or current).
Quoted 5 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 67
Quoted 3 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +3
-0+ + properties: + "usb-otg-vbus":Don't need quotes.
Acknowledged.
Quoted 18 lines
Quoted 18 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +17
-0+ type: object + $ref: /schemas/regulator/regulator.yaml + + properties: + regulator-name: true + regulator-min-microamp: + minimum: 0 + maximum: 6350000 + regulator-max-microamp: + minimum: 0 + maximum: 6350000 + regulator-min-microvolt: + minimum: 4480000 + maximum: 20800000 + regulator-max-microvolt: + minimum: 4480000 + maximum: 20800000
Quoted 9 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 90
Quoted 6 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +6
-0+ enable-gpios: + description: + The BQ25703 may require both a register write and a GPIO + toggle to enable the boost regulator. + + additionalProperties: trueNope.
Acknowledged.
Quoted 23 lines
Quoted 23 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +23
-0+ + required: + - regulator-name + - regulator-min-microamp + - regulator-max-microamp + - regulator-min-microvolt + - regulator-max-microvolt + +additionalProperties: false + +required: + - compatible + - reg + - power-supplies + - ti,charge-current + - ti,current-limit + - ti,max-charge-voltage + - ti,minimum-sys-voltage + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h>
Quoted 9 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 119
Quoted 6 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +6
-0+ #include <dt-bindings/pinctrl/rockchip.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + bq25703: bq25703@6b {charger@6b
Acknowledged.
Quoted 19 lines
Quoted 19 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +19
-0+ compatible = "ti,bq25703a"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; + power-supplies = <&fusb302>; + ti,charge-current = <2500000>; + ti,current-limit = <5000000>; + ti,max-charge-voltage = <8750000>; + ti,minimum-sys-voltage = <7400000>; + + regulators { + usb_otg_vbus: usb-otg-vbus { + enable-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + regulator-max-microamp = <960000>; + regulator-max-microvolt = <5088000>; + regulator-min-microamp = <512000>; + regulator-min-microvolt = <4992000>; + regulator-name = "usb_otg_vbus"; + };
Quoted 8 lines
Quoted 8 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +5
-0+ }; + }; + }; + +...Signature · 1 line
2.34.1
Thank you for your feedback,
Chris
Re: [RFC 1/5] dt-bindings: mfd: ti,bq25703a: Add TI BQ25703A Charger
Hi,
Quoted 12 lines · Chris Morgan
Quoted 12 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 33
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0+ + ti,charge-current: + description: + maximum current to apply to charging the battery + minimum: 0 + maximum: 8128000 + $ref: /schemas/types.yaml#/definitions/uint32I guess this is copied from other TI parts, but really this should move to a property with a unit suffix. Or these shared properties moved to a shared schema so we aren't redefining the type multiple times.
Quoted 6 lines
Quoted 1 line
Same for the others here.
Correct, I tried to reuse the same TI specific properties. I suppose I could also eliminate ti,charge-current and ti,max-charge-voltage, and then just require a phandle to a simple-battery node which contains those two values in a vendor independent form. What do you think?
Yes. The bindings using vendor specific properties for this are from before the simple battery binding existed.
Quoted 10 lines
ti,current-limit and ti,minimum-system-voltage though are other possible questions I have. Basically I could also create a vsys regulator that represents the vsys coming off this device too (I currently omit this entirely). This regulator wouldn't be programable but would report the existing input current and input voltage for the system, which in my case I'm pretty sure is stepped down to 5v or less and then fed into an RK806 PMIC (I lack the schematics so I don't know for sure). Of course if I did that then I'd have a valid reason to add a "regulators" node since I'd have more than one regulator.
I like this approach, since it allows properly describing the hardware setup in DT and avoids the vendor specific properties.
Greetings,
-- Sebastian
Re: [RFC 1/5] dt-bindings: mfd: ti,bq25703a: Add TI BQ25703A Charger
In reply to Rob HerringHi,
Quoted 62 lines · Rob Herring
Quoted 17 lines · Chris Morgan
From: Chris Morgan <[email protected]>
Document the Texas instruments BQ25703 series of charger managers/ buck/boost regulators.
Signed-off-by Chris Morgan <[email protected]>--- .../devicetree/bindings/mfd/ti,bq25703a.yaml | 143 ++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ti,bq25703a.yamlDocumentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +0
-0Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 7
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0@@ -0,0 +1,143 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ti,bq25703a.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: BQ25703 Charger Manager/Buck/Boost ConverterBQ25703A?
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 18
Quoted 11 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +11
-0+ +maintainers: + - Chris Morgan <[email protected]> + +properties: + compatible: + const: ti,bq25703a + + reg: + const: 0x6b + description: I2C slave addressDrop description.
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 26
Quoted 8 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +8
-0+ + interrupts: + maxItems: 1 + + power-supplies: + description: + phandle of the power supply that provides input power + $ref: /schemas/types.yaml#/definitions/phandleAlready has a type. You need a reference to
power-supply.yamlat the top level and 'maxItems: 1' here.Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 33
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0+ + ti,charge-current: + description: + maximum current to apply to charging the battery + minimum: 0 + maximum: 8128000 + $ref: /schemas/types.yaml#/definitions/uint32
Quoted 5 lines
I guess this is copied from other TI parts, but really this should move to a property with a unit suffix. Or these shared properties moved to a shared schema so we aren't redefining the type multiple times.
Same for the others here.
This is effectively information about the battery cells. The driver should use the simple battery infrastructure and reference it via monitored-battery. See also:
Documentation/devicetree/bindings/power/supply/battery.yaml
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 41
Quoted 7 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +7
-0+ ti,current-limit: + description: + maximum total input current allowed + minimum: 50000 + maximum: 6400000 + default: 3250000 + $ref: /schemas/types.yaml#/definitions/uint32
Use "input-current-limit-microamp" as property name.
Quoted 6 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 48
Quoted 6 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +6
-0+ ti,max-charge-voltage: + description: + maximum voltage to apply to charging the battery + minimum: 1024000 + maximum: 19200000 + $ref: /schemas/types.yaml#/definitions/uint32
That also belong into the simple-battery node.
Quoted 9 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 58
Quoted 9 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +9
-0+ ti,minimum-sys-voltage: + description: + minimum system voltage while on battery power, with default value + depending based on cell configuration + minimum: 1024000 + maximum: 16128000 + default: + enum: [3584000, 6144000, 9216000, 16128000] + $ref: /schemas/types.yaml#/definitions/uint32
Property should have -uvolt suffix.
Greetings,
-- Sebastian
Quoted 101 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 64
Quoted 5 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +5
-0+ regulators: + type: object + additionalProperties: false + description: + Boost converter regulator output of bq257xxDoesn't this apply to "usb-otg-vbus"?
Really, only one regulator, so you don't need a container node.
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 67
Quoted 3 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +3
-0+ + properties: + "usb-otg-vbus":Don't need quotes.
Quoted 13 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +13
-0+ type: object + $ref: /schemas/regulator/regulator.yaml + + properties: + regulator-name: true + regulator-min-microamp: + minimum: 0 + maximum: 6350000 + regulator-max-microamp: + minimum: 0 + maximum: 6350000 + regulator-min-microvolt: + minimum: 4480000Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 90
Quoted 10 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +10
-0+ maximum: 20800000 + regulator-max-microvolt: + minimum: 4480000 + maximum: 20800000 + enable-gpios: + description: + The BQ25703 may require both a register write and a GPIO + toggle to enable the boost regulator. + + additionalProperties: trueNope.
Quoted 19 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +19
-0+ + required: + - regulator-name + - regulator-min-microamp + - regulator-max-microamp + - regulator-min-microvolt + - regulator-max-microvolt + +additionalProperties: false + +required: + - compatible + - reg + - power-supplies + - ti,charge-current + - ti,current-limit + - ti,max-charge-voltage + - ti,minimum-sys-voltage +Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml line 119
Quoted 10 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +10
-0+examples: + - | + #include <dt-bindings/gpio/gpio.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/pinctrl/rockchip.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + bq25703: bq25703@6b {charger@6b
Quoted 27 lines
Documentation/devicetree/bindings/mfd/ti,bq25703a.yaml new file +24
-0+ compatible = "ti,bq25703a"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; + power-supplies = <&fusb302>; + ti,charge-current = <2500000>; + ti,current-limit = <5000000>; + ti,max-charge-voltage = <8750000>; + ti,minimum-sys-voltage = <7400000>; + + regulators { + usb_otg_vbus: usb-otg-vbus { + enable-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + regulator-max-microamp = <960000>; + regulator-max-microvolt = <5088000>; + regulator-min-microamp = <512000>; + regulator-min-microvolt = <4992000>; + regulator-name = "usb_otg_vbus"; + }; + }; + }; + }; + +...Signature · 1 line
2.34.1
RFC 2/5 mfd: bq257xx: Add support for BQ25703 core driver
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
The Texas Instruments BQ25703A is an integrated charger manager and boost converter.
The MFD driver initalizes the device for the regulator driver and power supply driver.
--- drivers/mfd/Kconfig | 11 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/bq257xx.c | 118 +++++++++++++++++++++++++++++++++++ include/linux/mfd/bq257xx.h | 120 ++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 drivers/mfd/bq257xx.c create mode 100644 include/linux/mfd/bq257xx.h
drivers/mfd/Kconfig +11 -0
@@ -1537,6 +1537,17 @@ config MFD_TI_LMU LM36274. It consists of backlight, LED and regulator driver. It provides consistent device controls for lighting functions. +config MFD_BQ257XX + tristate "TI BQ257XX Buck/Boost Charge Controller" + depends on I2C + select MFD_CORE + select REGMAP_I2C + help + Support Texas Instruments BQ25703 Buck/Boost converter with + charge controller. It consists of regulators that provide + system voltage and OTG voltage, and a charger manager for + batteries containing one or more cells. + config MFD_OMAP_USB_HOST bool "TI OMAP USBHS core and TLL driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
drivers/mfd/Makefile +1 -0
@@ -13,6 +13,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o +obj-$(CONFIG_MFD_BQ257XX) += bq257xx.o obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o obj-$(CONFIG_MFD_CS42L43) += cs42l43.o obj-$(CONFIG_MFD_CS42L43_I2C) += cs42l43-i2c.o
drivers/mfd/bq257xx.c new file +118 -0
118 lines not on this page · raw message
include/linux/mfd/bq257xx.h new file +120 -0
120 lines not on this page · raw message
Signature · 1 line
2.34.1
Lee Jones
maintainerRe: [RFC 2/5] mfd: bq257xx: Add support for BQ25703 core driver
Quoted 58 lines · Chris Morgan
From: Chris Morgan <[email protected]>
The Texas Instruments BQ25703A is an integrated charger manager and boost converter.
The MFD driver initalizes the device for the regulator driver and power supply driver.
Signed-off-by Chris Morgan <[email protected]>--- drivers/mfd/Kconfig | 11 ++++ drivers/mfd/Makefile | 1 + drivers/mfd/bq257xx.c | 118 +++++++++++++++++++++++++++++++++++ include/linux/mfd/bq257xx.h | 120 ++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+) create mode 100644 drivers/mfd/bq257xx.c create mode 100644 include/linux/mfd/bq257xx.hdrivers/mfd/Kconfig +11
-0@@ -1537,6 +1537,17 @@ config MFD_TI_LMU LM36274. It consists of backlight, LED and regulator driver. It provides consistent device controls for lighting functions. +config MFD_BQ257XX + tristate "TI BQ257XX Buck/Boost Charge Controller" + depends on I2C + select MFD_CORE + select REGMAP_I2C + help + Support Texas Instruments BQ25703 Buck/Boost converter with + charge controller. It consists of regulators that provide + system voltage and OTG voltage, and a charger manager for + batteries containing one or more cells. + config MFD_OMAP_USB_HOST bool "TI OMAP USBHS core and TLL driver" depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3drivers/mfd/Makefile +1
-0@@ -13,6 +13,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o +obj-$(CONFIG_MFD_BQ257XX) += bq257xx.o obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o obj-$(CONFIG_MFD_CS42L43) += cs42l43.o obj-$(CONFIG_MFD_CS42L43_I2C) += cs42l43-i2c.odrivers/mfd/bq257xx.c new file +0
-0
drivers/mfd/bq257xx.c line 2
Quoted 2 lines
drivers/mfd/bq257xx.c new file +2
-0@@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0 +/* BQ257XX MFD Driver
The top line of a multi-line comment should be empty.
Please drop _all_ mentions of "MFD" - it's not a thing.
drivers/mfd/bq257xx.c line 3
Quoted 1 line
drivers/mfd/bq257xx.c new file +1
-0+* Copyright (C) 2024 Chris Morgan <[email protected]>
'\n' here.
drivers/mfd/bq257xx.c line 5
Quoted 2 lines
drivers/mfd/bq257xx.c new file +2
-0+* Based off of BQ256XX Battery Charger Driver and +* Rockchip RK808 MFD Driver
You really don't have to mention this.
9 out of every 10 (I just made those figures up) drivers in the kernel take inspiration from existing ones. These sentences don't add anything IMHO.
Quoted 36 lines
drivers/mfd/bq257xx.c new file +36
-0+*/ + +#include <linux/device.h> +#include <linux/i2c.h> +#include <linux/mfd/bq257xx.h> +#include <linux/mfd/core.h> +#include <linux/regmap.h> + +static const struct regmap_range bq25703_readonly_reg_ranges[] = { +regmap_reg_range (BQ25703_CHARGER_STATUS ,BQ25703_MANUFACT_DEV_ID ), +}; + +static const struct regmap_access_table bq25703_writeable_regs = { + .no_ranges = bq25703_readonly_reg_ranges, + .n_no_ranges =ARRAY_SIZE (bq25703_readonly_reg_ranges), +}; + +static const struct regmap_range bq25703_volatile_reg_ranges[] = { +regmap_reg_range (BQ25703_CHARGE_OPTION_0 ,BQ25703_IIN_HOST ), +regmap_reg_range (BQ25703_CHARGER_STATUS ,BQ25703_ADC_OPTION ), +}; + +static const struct regmap_access_table bq25703_volatile_regs = { + .yes_ranges = bq25703_volatile_reg_ranges, + .n_yes_ranges =ARRAY_SIZE (bq25703_volatile_reg_ranges), +}; + +static const struct regmap_config bq25703_regmap_config = { + .reg_bits =8 , + .val_bits =16 , + .max_register =BQ25703_ADC_OPTION , + .cache_type =REGCACHE_RBTREE , + .wr_table = &bq25703_writeable_regs, + .volatile_table = &bq25703_volatile_regs, + .val_format_endian =REGMAP_ENDIAN_LITTLE , +};
drivers/mfd/bq257xx.c line 51
Quoted 10 lines
drivers/mfd/bq257xx.c new file +10
-0+ +static const struct mfd_cell bq25703_cells[] = { +MFD_CELL_NAME ("bq257xx-regulator" ), +MFD_CELL_NAME ("bq257xx-charger" ), +}; + +static int bq257xx_probe (struct i2c_client *client) +{ +struct device *dev = &client->dev; +struct bq257xx_device *bq;
Call this ddata.
drivers/mfd/bq257xx.c line 54
Quoted 3 lines
drivers/mfd/bq257xx.c new file +3
-0+const struct mfd_cell *cells; +int nr_cells; +int ret =0 ;
The pre-initialisation is redundant.
drivers/mfd/bq257xx.c line 61
Quoted 6 lines
drivers/mfd/bq257xx.c new file +6
-0+ bq =devm_kzalloc (dev,sizeof (*bq),GFP_KERNEL ); +if (!bq) +return -ENOMEM ; + + bq->client = client; + bq->dev = dev;
You don't need both.
drivers/mfd/bq257xx.c line 62
Quoted 1 line
drivers/mfd/bq257xx.c new file +1
-0+ bq->variant = (long )i2c_get_match_data (client);
Pretty sure this cast is not correct and maybe not even required.
drivers/mfd/bq257xx.c line 65
Quoted 2 lines
drivers/mfd/bq257xx.c new file +2
-0+switch (bq->variant) { +case BQ25703A :
I wouldn't add all of this complexity until its needed.
drivers/mfd/bq257xx.c line 66
Quoted 1 line
drivers/mfd/bq257xx.c new file +1
-0+ bq->regmap_cfg = &bq25703_regmap_config;
Where is this consumed?
drivers/mfd/bq257xx.c line 76
Quoted 10 lines
drivers/mfd/bq257xx.c new file +10
-0+ cells = bq25703_cells; + nr_cells =ARRAY_SIZE (bq25703_cells); +break ; +default : +dev_err (dev,"Unsupported BQ257XX ID %ld\n" , bq->variant); +return -EINVAL ; + } + + bq->regmap =devm_regmap_init_i2c (client, bq->regmap_cfg); +
Remove this line.
drivers/mfd/bq257xx.c line 87
Quoted 11 lines
drivers/mfd/bq257xx.c new file +11
-0+if (IS_ERR (bq->regmap)) { +dev_err (dev,"Failed to allocate register map\n" ); +return PTR_ERR (bq->regmap); + } + +i2c_set_clientdata (client, bq); + + ret =devm_mfd_add_devices (&client->dev,PLATFORM_DEVID_AUTO , + cells, nr_cells,NULL ,0 ,NULL ); +if (ret) { +dev_err (&client->dev,"failed to add MFD devices %d\n" , ret);
No such thing.
"Failed to register child devices"
q
Quoted 4 lines
drivers/mfd/bq257xx.c new file +4
-0+return ret; + } + +return ret;
drivers/mfd/bq257xx.c line 101
Quoted 10 lines
drivers/mfd/bq257xx.c new file +10
-0+} + +static const struct i2c_device_id bq257xx_i2c_ids[] = { + {"bq25703a" }, + {} +}; +MODULE_DEVICE_TABLE (i2c, bq257xx_i2c_ids); + +static const struct of_device_id bq257xx_of_match[] = { + { .compatible ="ti,bq25703a" , .data = (void *)BQ25703A , },
Cast almost certainly not required.
Quoted 5 lines
drivers/mfd/bq257xx.c new file +5
-0+ {} +}; +MODULE_DEVICE_TABLE (of, bq257xx_of_match); + +static struct i2c_driver bq257xx_driver = {
drivers/mfd/bq257xx.c line 116
Quoted 10 lines
drivers/mfd/bq257xx.c new file +10
-0+ .driver = { + .name = "bq257xx", + .of_match_table = bq257xx_of_match, + }, + .probe = bq257xx_probe, + .id_table = bq257xx_i2c_ids, +}; +module_i2c_driver (bq257xx_driver); + +MODULE_DESCRIPTION ("bq257xx buck/boost/charger MFD driver" );
Not an "MFD driver"
include/linux/mfd/bq257xx.h line 5
Quoted 13 lines
drivers/mfd/bq257xx.c new file +2
-0+MODULE_AUTHOR ("Chris Morgan <[email protected]>" ); +MODULE_LICENSE ("GPL" );include/linux/mfd/bq257xx.h new file +5
-0@@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0 +* Register definitions for TI BQ257XX +* Heavily based off of BQ256XX Battery Charger Driver +* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ +*/
All as above.
include/linux/mfd/bq257xx.h line 7
Quoted 1 line
include/linux/mfd/bq257xx.h new file +1
-0+#define BQ257XX_MANUFACTURER "Texas Instruments"
Errr, no thank you. Just use strings where you need them.
Quoted 89 lines
include/linux/mfd/bq257xx.h new file +89
-0+#define BQ25703_CHARGE_OPTION_0 0x00 +#define BQ25703_CHARGE_CURRENT 0x02 +#define BQ25703_MAX_CHARGE_VOLT 0x04 +#define BQ25703_OTG_VOLT 0x06 +#define BQ25703_OTG_CURRENT 0x08 +#define BQ25703_INPUT_VOLTAGE 0x0a +#define BQ25703_MIN_VSYS 0x0c +#define BQ25703_IIN_HOST 0x0e +#define BQ25703_CHARGER_STATUS 0x20 +#define BQ25703_PROCHOT_STATUS 0x22 +#define BQ25703_IIN_DPM 0x24 +#define BQ25703_ADCIBAT_CHG 0x28 +#define BQ25703_ADCIINCMPIN 0x2a +#define BQ25703_ADCVSYSVBAT 0x2c +#define BQ25703_MANUFACT_DEV_ID 0x2e +#define BQ25703_CHARGE_OPTION_1 0x30 +#define BQ25703_CHARGE_OPTION_2 0x32 +#define BQ25703_CHARGE_OPTION_3 0x34 +#define BQ25703_ADC_OPTION 0x3a + +#define BQ25703_EN_LWPWR BIT(15) +#define BQ25703_WDTMR_ADJ_MASK GENMASK(14, 13) +#define BQ25703_WDTMR_DISABLE 0 +#define BQ25703_WDTMR_5_SEC 1 +#define BQ25703_WDTMR_88_SEC 2 +#define BQ25703_WDTMR_175_SEC 3 + +#define BQ25703_ICHG_MASK GENMASK(12, 6) +#define BQ25703_ICHG_STEP_UA 64000 +#define BQ25703_ICHG_MIN_UA 64000 +#define BQ25703_ICHG_MAX_UA 8128000 + +#define BQ25703_MAX_CHARGE_VOLT_MASK GENMASK(15, 4) +#define BQ25703_VBATREG_STEP_UV 16000 +#define BQ25703_VBATREG_MIN_UV 1024000 +#define BQ25703_VBATREG_MAX_UV 19200000 + +#define BQ25703_OTG_VOLT_MASK GENMASK(13, 6) +#define BQ25703_OTG_VOLT_STEP_UV 64000 +#define BQ25703_OTG_VOLT_MIN_UV 4480000 +#define BQ25703_OTG_VOLT_MAX_UV 20800000 +#define BQ25703_OTG_VOLT_NUM_VOLT 256 + +#define BQ25703_OTG_CUR_MASK GENMASK(14, 8) +#define BQ25703_OTG_CUR_STEP_UA 50000 +#define BQ25703_OTG_CUR_MAX_UA 6350000 + +#define BQ25703_MINVSYS_MASK GENMASK(13, 8) +#define BQ25703_MINVSYS_STEP_UV 256000 +#define BQ25703_MINVSYS_MIN_UV 1024000 +#define BQ25703_MINVSYS_MAX_UV 16128000 + +#define BQ25703_STS_AC_STAT BIT(15) +#define BQ25703_STS_IN_FCHRG BIT(10) +#define BQ25703_STS_IN_PCHRG BIT(9) +#define BQ25703_STS_FAULT_ACOV BIT(7) +#define BQ25703_STS_FAULT_BATOC BIT(6) +#define BQ25703_STS_FAULT_ACOC BIT(5) + +#define BQ25703_IINDPM_MASK GENMASK(14, 8) +#define BQ25703_IINDPM_STEP_UA 50000 +#define BQ25703_IINDPM_MIN_UA 50000 +#define BQ25703_IINDPM_MAX_UA 6400000 +#define BQ25703_IINDPM_DEFAULT_UA 3300000 +#define BQ25703_IINDPM_OFFSET_UA 50000 + +#define BQ25703_ADCIBAT_DISCHG_MASK GENMASK(6, 0) +#define BQ25703_ADCIBAT_CHG_MASK GENMASK(14, 8) +#define BQ25703_ADCIBAT_CHG_STEP_UA 64000 +#define BQ25703_ADCIBAT_DIS_STEP_UA 256000 + +#define BQ25703_ADCIIN GENMASK(15, 8) +#define BQ25703_ADCIINCMPIN_STEP 50000 + +#define BQ25703_ADCVSYS_MASK GENMASK(15, 8) +#define BQ25703_ADCVBAT_MASK GENMASK(7, 0) +#define BQ25703_ADCVSYSVBAT_OFFSET_UV 2880000 +#define BQ25703_ADCVSYSVBAT_STEP 64000 + +#define BQ25703_ADC_CH_MASK GENMASK(7, 0) +#define BQ25703_ADC_CONV_EN BIT(15) +#define BQ25703_ADC_START BIT(14) +#define BQ25703_ADC_FULL_SCALE BIT(13) +#define BQ25703_ADC_CMPIN_EN BIT(7) +#define BQ25703_ADC_VBUS_EN BIT(6) +#define BQ25703_ADC_PSYS_EN BIT(5) +#define BQ25703_ADC_IIN_EN BIT(4) +#define BQ25703_ADC_IDCHG_EN BIT(3) +#define BQ25703_ADC_ICHG_EN BIT(2)
include/linux/mfd/bq257xx.h line 107
Quoted 10 lines
include/linux/mfd/bq257xx.h new file +10
-0+#define BQ25703_ADC_VSYS_EN BIT(1) +#define BQ25703_ADC_VBAT_EN BIT(0) + +#define BQ25703_EN_OTG_MASK BIT(12) + +enum bq257xx_id { +BQ25703A , +}; + +/**
Are you sure you want to use kernel-doc here?
I would advise against it.
include/linux/mfd/bq257xx.h line 112
Quoted 5 lines
include/linux/mfd/bq257xx.h new file +5
-0+* struct bq257xx_device - +* @client: i2c client structure +* @regmap: register map structure +* @dev: device structure +* @regmap_cfg: device specific regmap cfg
It's also wrong. Did you test build with W=1?
Quoted 11 lines
include/linux/mfd/bq257xx.h new file +8
-0+*/ +struct bq257xx_device { +struct i2c_client *client; +struct regmap *regmap; +struct device *dev; +const struct regmap_config *regmap_cfg; +long variant; +};Signature · 1 line
2.34.1
Signature · 1 line
Lee Jones [李琼斯]
RFC 3/5 power: supply: bq257xx: Add support for BQ257XX charger manager
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add support for the charger function of the BQ257XX. The device is capable of charging batteries with a layout of 1 to 4 cells in series.
--- drivers/power/supply/Kconfig | 7 + drivers/power/supply/Makefile | 1 + drivers/power/supply/bq257xx_charger.c | 811 +++++++++++++++++++++++++ 3 files changed, 819 insertions(+) create mode 100644 drivers/power/supply/bq257xx_charger.c
drivers/power/supply/Kconfig +7 -0
@@ -720,6 +720,13 @@ config CHARGER_BQ2515X rail, ADC for battery and system monitoring, and push-button controller. +config CHARGER_BQ257XX + tristate "TI BQ257XX battery charger family" + depends on MFD_BQ257XX + help + Say Y to enable support for the TI BQ257XX family of battery + charging integrated circuits. + config CHARGER_BQ25890 tristate "TI BQ25890 battery charger driver" depends on I2C
drivers/power/supply/Makefile +1 -0
@@ -93,6 +93,7 @@ obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o obj-$(CONFIG_CHARGER_BQ2515X) += bq2515x_charger.o +obj-$(CONFIG_CHARGER_BQ257XX) += bq257xx_charger.o obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o obj-$(CONFIG_CHARGER_BQ25980) += bq25980_charger.o obj-$(CONFIG_CHARGER_BQ256XX) += bq256xx_charger.o
drivers/power/supply/bq257xx_charger.c new file +811 -0
811 lines not on this page · raw message
Signature · 1 line
2.34.1
Re: [RFC 3/5] power: supply: bq257xx: Add support for BQ257XX charger manager
Hi,
Quoted 8 lines · Chris Morgan
From: Chris Morgan <[email protected]>
Add support for the charger function of the BQ257XX. The device is capable of charging batteries with a layout of 1 to 4 cells in series.
Signed-off-by Chris Morgan <[email protected]>---
I skipped reviewing the parts related to the requested binding changes.
Quoted 42 lines
drivers/power/supply/Kconfig | 7 + drivers/power/supply/Makefile | 1 + drivers/power/supply/bq257xx_charger.c | 811 +++++++++++++++++++++++++ 3 files changed, 819 insertions(+) create mode 100644 drivers/power/supply/bq257xx_charger.cdrivers/power/supply/Kconfig +7
-0@@ -720,6 +720,13 @@ config CHARGER_BQ2515X rail, ADC for battery and system monitoring, and push-button controller. +config CHARGER_BQ257XX + tristate "TI BQ257XX battery charger family" + depends on MFD_BQ257XX + help + Say Y to enable support for the TI BQ257XX family of battery + charging integrated circuits. + config CHARGER_BQ25890 tristate "TI BQ25890 battery charger driver" depends on I2Cdrivers/power/supply/Makefile +1
-0@@ -93,6 +93,7 @@ obj-$(CONFIG_CHARGER_BQ24190) += bq24190_charger.o obj-$(CONFIG_CHARGER_BQ24257) += bq24257_charger.o obj-$(CONFIG_CHARGER_BQ24735) += bq24735-charger.o obj-$(CONFIG_CHARGER_BQ2515X) += bq2515x_charger.o +obj-$(CONFIG_CHARGER_BQ257XX) += bq257xx_charger.o obj-$(CONFIG_CHARGER_BQ25890) += bq25890_charger.o obj-$(CONFIG_CHARGER_BQ25980) += bq25980_charger.o obj-$(CONFIG_CHARGER_BQ256XX) += bq256xx_charger.odrivers/power/supply/bq257xx_charger.c new file +0
-0
drivers/power/supply/bq257xx_charger.c line 9
Quoted 9 lines
drivers/power/supply/bq257xx_charger.c new file +9
-0@@ -0,0 +1,811 @@ +// SPDX-License-Identifier: GPL-2.0 +/* BQ257XX Battery Charger Driver +* Copyright (C) 2024 Chris Morgan <[email protected]> +* Based off of BQ256XX Battery Charger Driver +* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ +*/ + +#include <linux/bitfield.h> +#include <linux/i2c.h>
is the i2c header actually used?
drivers/power/supply/bq257xx_charger.c line 11
Quoted 2 lines
drivers/power/supply/bq257xx_charger.c new file +2
-0+#include <linux/mfd/bq257xx.h> +#include <linux/moduleparam.h>
development leftover?
Quoted 333 lines
drivers/power/supply/bq257xx_charger.c new file +333
-0+#include <linux/platform_device.h> +#include <linux/power_supply.h> +#include <linux/regmap.h> + +/* Forward declaration of driver data. */ +struct bq257xx_chg ; + +/** +* struct bq257xx_chip_info - chip specific routines +* @bq257xx_hw_init: init function for hw +* @bq257xx_hw_shutdown: shutdown function for hw +* @bq257xx_get_state: get and update state of hardware +* @bq257xx_set_ichg: set maximum charge current (in uA) +* @bq257xx_set_vbatreg: set maximum charge voltage (in uV) +* @bq257xx_set_iindpm: set maximum input current (in uA) +* +* Functions for variants of the BQ257XX IC revisions that are made +* available generic portions of the driver code (such as the main +* probe function). +*/ +struct bq257xx_chip_info { +int (*bq257xx_hw_init)(struct bq257xx_chg *pdata); +void (*bq257xx_hw_shutdown)(struct bq257xx_chg *pdata); +int (*bq257xx_get_state)(struct bq257xx_chg *pdata); +int (*bq257xx_set_ichg)(struct bq257xx_chg *pdata,int ichg); +int (*bq257xx_set_vbatreg)(struct bq257xx_chg *pdata,int vbatreg); +int (*bq257xx_set_iindpm)(struct bq257xx_chg *pdata,int iindpm); +}; + +/** +* struct bq257xx_chg - driver data for charger +* @bq257xx_chip_info: hw specific functions +* @bq257xx_device: parent MFD device +* @charger: power supply device +* @online: charger input is present +* @fast_charge: charger is in fast charge mode +* @pre_charge: charger is in pre-charge mode +* @ov_fault: charger reports over voltage fault +* @batoc_fault: charger reports battery over current fault +* @oc_fault: charger reports over current fault +* @usb_type: USB type reported from parent power supply +* @supplied: Status of parent power supply +* @iindpm_max: maximum input current limit (uA) +* @vbat_max: maximum charge voltage (uV) +* @ichg_max: maximum charge current (uA) +* @vsys_min: minimum system voltage (uV) +*/ +struct bq257xx_chg { +const struct bq257xx_chip_info *chip; +struct bq257xx_device *bq; +struct power_supply *charger; +bool online; +bool fast_charge; +bool pre_charge; +bool ov_fault; +bool batoc_fault; +bool oc_fault; +int usb_type; +int supplied; +u32 iindpm_max; +u32 vbat_max; +u32 ichg_max; +u32 vsys_min; +}; + +/** +* bq25703_get_state() - Get the current state of the device +* @pdata: driver platform data +* +* Get the current state of the charger. Check if the charger is +* powered, what kind of charge state (if any) the device is in, +* and if there are any active faults. +* +* Return: Returns 0 on success, or error on failure to read device. +*/ +static int bq25703_get_state (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_CHARGER_STATUS , ®); +if (ret) +return ret; + + pdata->online = reg &BQ25703_STS_AC_STAT ; + pdata->fast_charge = reg &BQ25703_STS_IN_FCHRG ; + pdata->pre_charge = reg &BQ25703_STS_IN_PCHRG ; + pdata->ov_fault = reg &BQ25703_STS_FAULT_ACOV ; + pdata->batoc_fault = reg &BQ25703_STS_FAULT_BATOC ; + pdata->oc_fault = reg &BQ25703_STS_FAULT_ACOC ; + +return 0 ; +} + +/** +* bq25703_get_min_vsys() - Get the minimum system voltage +* @pdata: driver platform data +* +* Return: Returns minimum system voltage in uV on success, or error on +* failure to read device. +*/ +static int bq25703_get_min_vsys (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_MIN_VSYS , + ®); +if (ret) +return ret; + + reg =FIELD_GET (BQ25703_MINVSYS_MASK , reg); +return (reg *BQ25703_MINVSYS_STEP_UV ) +BQ25703_MINVSYS_MIN_UV ; +} + +/** +* bq25703_set_min_vsys() - Set the minimum system voltage +* @pdata: driver platform data +* @ichg: voltage value to set in uV. +* +* This function takes a requested minimum system voltage value, clamps +* it between the minimum supported value by the charger and a user +* defined minimum system value, and then writes the value to the +* appropriate register. +* +* Return: Returns 0 on success or error if an error occurs. +*/ +static int bq25703_set_min_vsys (struct bq257xx_chg *pdata,int vsys) +{ +unsigned int reg; +int vsys_min = pdata->vsys_min; + + vsys =clamp (vsys,BQ25703_MINVSYS_MIN_UV , vsys_min); + reg = ((vsys -BQ25703_MINVSYS_MIN_UV ) /BQ25703_MINVSYS_STEP_UV ); + reg =FIELD_PREP (BQ25703_MINVSYS_MASK , reg); + +return regmap_write (pdata->bq->regmap,BQ25703_MIN_VSYS , + reg); +} + +/** +* bq25703_get_cur() - Get the reported current from the battery +* @pdata: driver platform data +* +* Return: Returns reported current from battery in uA as an absolute +* value (charge and discharge are both positive integers). +* Returns error if unable to read register value. +*/ +static int bq25703_get_cur (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_ADCIBAT_CHG , ®); +if (ret <0 ) +return ret; + +if (pdata->online) +return FIELD_GET (BQ25703_ADCIBAT_CHG_MASK , reg) * +BQ25703_ADCIBAT_CHG_STEP_UA ; +else +return FIELD_GET (BQ25703_ADCIBAT_DISCHG_MASK , reg) * +BQ25703_ADCIBAT_DIS_STEP_UA ; +} + +/** +* bq25703_get_ichg_cur() - Get the maximum reported charge current +* @pdata: driver platform data +* +* Return: Returns maximum set charge current from charger in uA. +* Returns error if unable to read register value. +*/ +static int bq25703_get_ichg_cur (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_CHARGE_CURRENT , ®); +if (ret) +return ret; + +return FIELD_GET (BQ25703_ICHG_MASK , reg) *BQ25703_ICHG_STEP_UA ; +} + +/** +* bq25703_set_ichg_cur() - Set the maximum charge current +* @pdata: driver platform data +* @ichg: current value to set in uA. +* +* This function takes a requested maximum charge current value, clamps +* it between the minimum supported value by the charger and a user +* defined maximum charging value, and then writes the value to the +* appropriate register. +* +* Return: Returns 0 on success or error if an error occurs. +*/ +static int bq25703_set_ichg_cur (struct bq257xx_chg *pdata,int ichg) +{ +unsigned int reg; +int ichg_max = pdata->ichg_max; + + ichg =clamp (ichg,BQ25703_ICHG_MIN_UA , ichg_max); + reg =FIELD_PREP (BQ25703_ICHG_MASK , (ichg /BQ25703_ICHG_STEP_UA )); + +return regmap_write (pdata->bq->regmap,BQ25703_CHARGE_CURRENT , + reg); +} + +/** +* bq25703_get_chrg_volt() - Get the maximum set charge voltage +* @pdata: driver platform data +* +* Return: Returns maximum set charge voltage from charger in uV. +* Returns error if unable to read register value. +*/ +static int bq25703_get_chrg_volt (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_MAX_CHARGE_VOLT , + ®); +if (ret) +return ret; + +return FIELD_GET (BQ25703_MAX_CHARGE_VOLT_MASK , reg) * +BQ25703_VBATREG_STEP_UV ; +} + +/** +* bq25703_set_chrg_volt() - Set the maximum charge voltage +* @pdata: driver platform data +* @vbat: voltage value to set in uV. +* +* This function takes a requested maximum charge voltage value, clamps +* it between the minimum supported value by the charger and a user +* defined maximum charging value, and then writes the value to the +* appropriate register. +* +* Return: Returns 0 on success or error if an error occurs. +*/ +static int bq25703_set_chrg_volt (struct bq257xx_chg *pdata,int vbat) +{ +unsigned int reg; +int vbat_max = pdata->vbat_max; + + vbat =clamp (vbat,BQ25703_VBATREG_MIN_UV , vbat_max); + + reg =FIELD_PREP (BQ25703_MAX_CHARGE_VOLT_MASK , + (vbat /BQ25703_VBATREG_STEP_UV )); + +return regmap_write (pdata->bq->regmap,BQ25703_MAX_CHARGE_VOLT , + reg); +} + +/** +* bq25703_get_iindpm() - Get the maximum set input current +* @pdata: driver platform data +* +* Read the actual input current limit from the device. This can differ +* from the value programmed due to some autonomous functions that may +* be enabled (but are not currently). This is why there is a different +* register used. +* +* Return: Returns maximum set input current from charger in uA. +* Returns error if unable to read register value. +*/ +static int bq25703_get_iindpm (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_IIN_DPM , ®); +if (ret) +return ret; + + reg =FIELD_GET (BQ25703_IINDPM_MASK , reg); +return (reg *BQ25703_IINDPM_STEP_UA ) +BQ25703_IINDPM_OFFSET_UA ; +} + +/** +* bq25703_set_iindpm() - Set the maximum input current +* @pdata: driver platform data +* @iindpm: current value in uA. +* +* This function takes a requested maximum input current value, clamps +* it between the minimum supported value by the charger and a user +* defined maximum input value, and then writes the value to the +* appropriate register. +* +* Return: Returns 0 on success or error if an error occurs. +*/ +static int bq25703_set_iindpm (struct bq257xx_chg *pdata,int iindpm) +{ +unsigned int reg; +int iindpm_max = pdata->iindpm_max; + + iindpm =clamp (iindpm,BQ25703_IINDPM_MIN_UA , iindpm_max); + + reg = ((iindpm -BQ25703_IINDPM_OFFSET_UA ) /BQ25703_IINDPM_STEP_UA ); + +return regmap_write (pdata->bq->regmap,BQ25703_IIN_HOST , +FIELD_PREP (BQ25703_IINDPM_MASK , reg)); +} + +/** +* bq25703_get_vbat() - Get the reported voltage from the battery +* @pdata: driver platform data +* +* Return: Returns reported voltage from battery in uV. +* Returns error if unable to read register value. +*/ +static int bq25703_get_vbat (struct bq257xx_chg *pdata) +{ +unsigned int reg; +int ret; + + ret =regmap_read (pdata->bq->regmap,BQ25703_ADCVSYSVBAT , ®); +if (ret) +return ret; + + reg =FIELD_GET (BQ25703_ADCVBAT_MASK , reg); + +return (reg *BQ25703_ADCVSYSVBAT_STEP ) +BQ25703_ADCVSYSVBAT_OFFSET_UV ; + +} + +/** +* bq25703_hw_init() - Set all the required registers to init the charger +* @pdata: driver platform data +* +* Initialize the BQ25703 by first disabling the watchdog timer (which +* shuts off the charger in the absence of periodic writes). Then, set
drivers/power/supply/bq257xx_charger.c line 354
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+* the charge current, charge voltage, minimum system voltage, and +* input current limit. Disable low power mode to allow ADCs and +* interrupts. Enable the ADC, start the ADC, set the ADC scale to +* full, and enable each individual ADC channel. +* +* Return: Returns 0 on success or error code on error. +*/ +static int bq25703_hw_init (struct bq257xx_chg *pdata) +{ +int ret =0 ;
You need the regmap a bunch of times, so create a local variable for it :)
Quoted 59 lines
drivers/power/supply/bq257xx_charger.c new file +59
-0+ +regmap_update_bits (pdata->bq->regmap,BQ25703_CHARGE_OPTION_0 , +BQ25703_WDTMR_ADJ_MASK , +FIELD_PREP (BQ25703_WDTMR_ADJ_MASK , +BQ25703_WDTMR_DISABLE )); + + ret = pdata->chip->bq257xx_set_ichg (pdata, pdata->ichg_max); +if (ret) +return ret; + + ret = pdata->chip->bq257xx_set_vbatreg (pdata, pdata->vbat_max); +if (ret) +return ret; + + ret =bq25703_set_min_vsys (pdata, pdata->vsys_min); +if (ret) +return ret; + + ret = pdata->chip->bq257xx_set_iindpm (pdata, pdata->iindpm_max); +if (ret) +return ret; + +regmap_update_bits (pdata->bq->regmap,BQ25703_CHARGE_OPTION_0 , +BQ25703_EN_LWPWR , !BQ25703_EN_LWPWR ); + +regmap_update_bits (pdata->bq->regmap,BQ25703_ADC_OPTION , +BQ25703_ADC_CONV_EN ,BQ25703_ADC_CONV_EN ); + +regmap_update_bits (pdata->bq->regmap,BQ25703_ADC_OPTION , +BQ25703_ADC_START ,BQ25703_ADC_START ); + +regmap_update_bits (pdata->bq->regmap,BQ25703_ADC_OPTION , +BQ25703_ADC_FULL_SCALE ,BQ25703_ADC_FULL_SCALE ); + +regmap_update_bits (pdata->bq->regmap,BQ25703_ADC_OPTION , +BQ25703_ADC_CH_MASK , + (BQ25703_ADC_CMPIN_EN |BQ25703_ADC_VBUS_EN | +BQ25703_ADC_PSYS_EN |BQ25703_ADC_IIN_EN | +BQ25703_ADC_IDCHG_EN |BQ25703_ADC_ICHG_EN | +BQ25703_ADC_VSYS_EN |BQ25703_ADC_VBAT_EN )); + +return ret; +} + +/** +* bq25703_hw_shutdown() - Set registers for shutdown +* @pdata: driver platform data +* +* Enable low power mode for the device while in shutdown. +*/ +static void bq25703_hw_shutdown (struct bq257xx_chg *pdata) +{ +regmap_update_bits (pdata->bq->regmap,BQ25703_CHARGE_OPTION_0 , +BQ25703_EN_LWPWR ,BQ25703_EN_LWPWR ); +} + +static int bq257xx_set_charger_property (struct power_supply *psy, +enum power_supply_property prop, +const union power_supply_propval *val)
drivers/power/supply/bq257xx_charger.c line 423
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+{ +struct bq257xx_chg *pdata =power_supply_get_drvdata (psy); +int ret = -EINVAL ; + +switch (prop) { +case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT : + ret = pdata->chip->bq257xx_set_iindpm (pdata, val->intval); +if (ret) +return ret; +break ;
return pdata->chip->bq257xx_set_iindpm(...);
drivers/power/supply/bq257xx_charger.c line 429
Quoted 6 lines
drivers/power/supply/bq257xx_charger.c new file +6
-0+ +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX : + ret = pdata->chip->bq257xx_set_vbatreg (pdata, val->intval); +if (ret) +return ret; +break ;
same.
drivers/power/supply/bq257xx_charger.c line 435
Quoted 5 lines
drivers/power/supply/bq257xx_charger.c new file +5
-0+case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX : + ret = pdata->chip->bq257xx_set_ichg (pdata, val->intval); +if (ret) +return ret; +break ;
same.
drivers/power/supply/bq257xx_charger.c line 436
Quoted 2 lines
drivers/power/supply/bq257xx_charger.c new file +2
-0+default : +break ;
return -EINVAL
drivers/power/supply/bq257xx_charger.c line 121
Quoted 3 lines
drivers/power/supply/bq257xx_charger.c new file +3
-0+ } + +return ret;
get rid of this and ret.
Quoted 37 lines
drivers/power/supply/bq257xx_charger.c new file +37
-0+} + +static int bq257xx_get_charger_property (struct power_supply *psy, +enum power_supply_property psp, +union power_supply_propval *val) +{ +struct bq257xx_chg *pdata =power_supply_get_drvdata (psy); +int ret =0 ; + + ret = pdata->chip->bq257xx_get_state (pdata); +if (ret) +return ret; + +switch (psp) { +case POWER_SUPPLY_PROP_STATUS : +if (!pdata->online) + val->intval =POWER_SUPPLY_STATUS_DISCHARGING ; +else if (!bq25703_get_cur (pdata)) + val->intval =POWER_SUPPLY_STATUS_NOT_CHARGING ; +else if (pdata->fast_charge || pdata->pre_charge) + val->intval =POWER_SUPPLY_STATUS_CHARGING ; +else + val->intval =POWER_SUPPLY_STATUS_NOT_CHARGING ; +break ; + +case POWER_SUPPLY_PROP_HEALTH : +if (pdata->ov_fault || pdata->batoc_fault) + val->intval =POWER_SUPPLY_HEALTH_OVERVOLTAGE ; +else if (pdata->oc_fault) + val->intval =POWER_SUPPLY_HEALTH_OVERCURRENT ; +else + val->intval =POWER_SUPPLY_HEALTH_GOOD ; +break ; + +case POWER_SUPPLY_PROP_MANUFACTURER : + val->strval =BQ257XX_MANUFACTURER ; +break ;
drivers/power/supply/bq257xx_charger.c line 488
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+ +case POWER_SUPPLY_PROP_ONLINE : + val->intval = pdata->online; +break ; + +case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT : + ret =bq25703_get_iindpm (pdata); +if (ret <0 ) +return ret; + val->intval = ret;
Maybe feed val as second argument to bq25703_get_iindpm(), so that you can just do
return bq25703_get_iindpm(pdata, val);
drivers/power/supply/bq257xx_charger.c line 496
Quoted 8 lines
drivers/power/supply/bq257xx_charger.c new file +8
-0+break ; + +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX : + ret =bq25703_get_chrg_volt (pdata); +if (ret <0 ) +return ret; + val->intval = ret; +break ;
same.
drivers/power/supply/bq257xx_charger.c line 507
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+case POWER_SUPPLY_PROP_CURRENT_NOW : + ret =bq25703_get_cur (pdata); +if (ret <0 ) +return ret; + +if (pdata->online) + val->intval = ret; +else + val->intval = -ret; +break ;
same, if you move the online check into bq25703_get_cur.
drivers/power/supply/bq257xx_charger.c line 514
Quoted 6 lines
drivers/power/supply/bq257xx_charger.c new file +6
-0+case POWER_SUPPLY_PROP_VOLTAGE_NOW : + ret =bq25703_get_vbat (pdata); +if (ret <0 ) +return ret; + val->intval = ret; +break ;
same.
drivers/power/supply/bq257xx_charger.c line 521
Quoted 6 lines
drivers/power/supply/bq257xx_charger.c new file +6
-0+case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX : + ret =bq25703_get_ichg_cur (pdata); +if (ret <0 ) +return ret; + val->intval = ret; +break ;
same.
drivers/power/supply/bq257xx_charger.c line 528
Quoted 6 lines
drivers/power/supply/bq257xx_charger.c new file +6
-0+case POWER_SUPPLY_PROP_VOLTAGE_MIN : + ret =bq25703_get_min_vsys (pdata); +if (ret <0 ) +return ret; + val->intval = ret; +break ;
same.
Quoted 108 lines
drivers/power/supply/bq257xx_charger.c new file +108
-0+case POWER_SUPPLY_PROP_USB_TYPE : + val->intval = pdata->usb_type; +break ; + +default : +return -EINVAL ; + } + +return ret; +} + +static enum power_supply_property bq257xx_power_supply_props[] = { +POWER_SUPPLY_PROP_MANUFACTURER , +POWER_SUPPLY_PROP_STATUS , +POWER_SUPPLY_PROP_ONLINE , +POWER_SUPPLY_PROP_HEALTH , +POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT , +POWER_SUPPLY_PROP_CURRENT_NOW , +POWER_SUPPLY_PROP_VOLTAGE_NOW , +POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX , +POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX , +POWER_SUPPLY_PROP_VOLTAGE_MIN , +POWER_SUPPLY_PROP_USB_TYPE , +}; + +static int bq257xx_property_is_writeable (struct power_supply *psy, +enum power_supply_property prop) +{ +switch (prop) { +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX : +case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX : +case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT : +return true; +default : +return false; + } +} + +static enum power_supply_usb_type bq25703_usb_types[] = { +POWER_SUPPLY_USB_TYPE_C , +POWER_SUPPLY_USB_TYPE_PD , +POWER_SUPPLY_USB_TYPE_PD_DRP , +POWER_SUPPLY_USB_TYPE_PD_PPS , +POWER_SUPPLY_USB_TYPE_UNKNOWN , +}; + +/** +* bq257xx_external_power_changed() - Handler for external power change +* @psy: Power supply data +* +* When the external power into the charger is changed, check the USB +* type so that it can be reported. Additionally, update the max input +* current and max charging current to the value reported if it is a +* USB PD charger, otherwise use the default value. Note that each time +* a charger is removed the max charge current register is erased, so +* it must be set again each time the input changes or the device will +* not charge. +*/ +static void bq257xx_external_power_changed (struct power_supply *psy) +{ +struct bq257xx_chg *pdata =power_supply_get_drvdata (psy); +union power_supply_propval val; +int ret; +int imax = pdata->iindpm_max; + + pdata->chip->bq257xx_get_state (pdata); + + pdata->supplied =power_supply_am_i_supplied (pdata->charger); +if (pdata->supplied <0 ) +return ; + +if (pdata->supplied ==0 ) + goto out; + + ret =power_supply_get_property_from_supplier (psy, +POWER_SUPPLY_PROP_USB_TYPE , + &val); +if (ret) +return ; + + pdata->usb_type = val.intval; + +if ((pdata->usb_type ==POWER_SUPPLY_USB_TYPE_PD ) || + (pdata->usb_type ==POWER_SUPPLY_USB_TYPE_PD_DRP ) || + (pdata->usb_type ==POWER_SUPPLY_USB_TYPE_PD )) { + ret =power_supply_get_property_from_supplier (psy, +POWER_SUPPLY_PROP_CURRENT_MAX , + &val); +if (ret) +return ; + +if (val.intval) + imax = val.intval; + } + +if (pdata->supplied) { + pdata->chip->bq257xx_set_ichg (pdata, imax); + pdata->chip->bq257xx_set_iindpm (pdata, imax); + pdata->chip->bq257xx_set_vbatreg (pdata, pdata->vbat_max); + } + +out: +power_supply_changed (psy); +} + +static irqreturn_t bq257xx_irq_handler_thread (int irq,void *private) +{ +struct bq257xx_chg *pdata = private;
drivers/power/supply/bq257xx_charger.c line 647
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+ +bq257xx_external_power_changed (pdata->charger); +return IRQ_HANDLED ; +} + +static const struct power_supply_desc bq257xx_power_supply_desc = { + .name ="bq257xx-charger" , + .type =POWER_SUPPLY_TYPE_USB , + .usb_types = bq25703_usb_types, + .num_usb_types =ARRAY_SIZE (bq25703_usb_types),
This recently changed into a bitmask.
Quoted 18 lines
drivers/power/supply/bq257xx_charger.c new file +18
-0+ .properties = bq257xx_power_supply_props, + .num_properties = ARRAY_SIZE(bq257xx_power_supply_props), + .get_property = bq257xx_get_charger_property, + .set_property = bq257xx_set_charger_property, + .property_is_writeable = bq257xx_property_is_writeable, + .external_power_changed = bq257xx_external_power_changed, +}; + +static const struct bq257xx_chip_info bq25703_chip_info = { + .bq257xx_hw_init = &bq25703_hw_init, + .bq257xx_hw_shutdown = &bq25703_hw_shutdown, + .bq257xx_get_state = &bq25703_get_state, + .bq257xx_set_ichg = &bq25703_set_ichg_cur, + .bq257xx_set_vbatreg = &bq25703_set_chrg_volt, + .bq257xx_set_iindpm = &bq25703_set_iindpm, +}; + +static int bq257xx_power_supply_init(struct bq257xx_chg *pdata,
drivers/power/supply/bq257xx_charger.c line 675
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+ struct power_supply_config *psy_cfg, struct device *dev) +{ + pdata->charger = devm_power_supply_register(dev, + &bq257xx_power_supply_desc, + psy_cfg); +if (IS_ERR (pdata->charger)) { +dev_err_probe (dev,PTR_ERR (pdata->charger), +"power supply register charger failed: %ld\n" , +PTR_ERR (pdata->charger)); +return PTR_ERR (pdata->charger);
dev_err_probe() returns the error code, so you can just do return dev_err_probe(...). Also it prints the error code, so no need for the ": %ld" part either.
After that simplification I don't see the point in having an extra function for this.
Quoted 14 lines
drivers/power/supply/bq257xx_charger.c new file +14
-0+ } + +return 0 ; +} + +/** +* bq257xx_parse_dt() - Parse the device tree for required properties +* @pdata: driver platform data +* @psy_cfg: power supply config data +* @dev: device struct +* +* Read the device tree to identify the minimum system voltage, the +* maximum charge current, the maximum charge voltage, and the maximum +* input current.
drivers/power/supply/bq257xx_charger.c line 699
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+* +* Return: Returns 0 on success or error code on error. +*/ +static int bq257xx_parse_dt (struct bq257xx_chg *pdata, +struct power_supply_config *psy_cfg,struct device *dev) +{ +int ret =0 ; + + psy_cfg->drv_data = pdata; + psy_cfg->of_node = dev->of_node;
replace the last one with
psy_cfg.fwnode = dev_fwnode(dev);
drivers/power/supply/bq257xx_charger.c line 706
Quoted 6 lines
drivers/power/supply/bq257xx_charger.c new file +6
-0+ ret =device_property_read_u32 (dev, +"ti,minimum-sys-voltage" , + &pdata->vsys_min); +if (ret) { +dev_err (dev,"Cannot read ti,minimum-sys-voltage from dt\n" ); +return ret;
return dev_err_probe(dev, ret, ...);
Quoted 13 lines
drivers/power/supply/bq257xx_charger.c new file +13
-0+ } + + ret =device_property_read_u32 (dev, +"ti,charge-current" , + &pdata->ichg_max); +if (ret) { +dev_err (dev,"Cannot read ti,charge-current from dt\n" ); +return ret; + } + + ret =device_property_read_u32 (dev, +"ti,max-charge-voltage" , + &pdata->vbat_max);
drivers/power/supply/bq257xx_charger.c line 729
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+if (ret) { +dev_err (dev,"Cannot read ti,max-charge-voltage from dt\n" ); +return ret; + } + + ret =device_property_read_u32 (dev, +"ti,current-limit" , + &pdata->iindpm_max); +if (ret) + pdata->iindpm_max =BQ25703_IINDPM_DEFAULT_UA ;
same for the above, but will change anyways because of binding change.
Quoted 4 lines
drivers/power/supply/bq257xx_charger.c new file +4
-0+ +return 0 ; +} +
drivers/power/supply/bq257xx_charger.c line 743
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+static int bq257xx_charger_probe (struct platform_device *pdev) +{ +struct device *dev = &pdev->dev; +struct bq257xx_device *bq =dev_get_drvdata (pdev->dev.parent); +struct bq257xx_chg *pdata; +struct power_supply_config psy_cfg = { }; +int ret; + + pdev->dev.of_node = pdev->dev.parent->of_node; + pdev->dev.of_node_reused = true;
replace above two lines with
device_set_of_node_from_dev(dev, pdev->dev.parent);
drivers/power/supply/bq257xx_charger.c line 747
Quoted 4 lines
drivers/power/supply/bq257xx_charger.c new file +4
-0+ + pdata =devm_kzalloc (&pdev->dev,sizeof (struct bq257xx_chg ),GFP_KERNEL ); +if (!pdata) +return -ENOMEM ;
use sizeof(*pdata)
drivers/power/supply/bq257xx_charger.c line 761
Quoted 13 lines
drivers/power/supply/bq257xx_charger.c new file +13
-0+ pdata->bq = bq; + +switch (pdata->bq->variant) { +case BQ25703A : + pdata->chip = &bq25703_chip_info; +break ; +default : +return -EINVAL ; + } + + ret =bq257xx_parse_dt (pdata, &psy_cfg, dev); +if (ret) { +dev_err (dev,"Failed to read device tree properties%d\n" , ret);
no need for this error message, since bq257xx_parse_dt already prints a message for all error cases.
Quoted 40 lines
drivers/power/supply/bq257xx_charger.c new file +40
-0+return ret; + } + + ret = pdata->chip->bq257xx_hw_init (pdata); +if (ret) { +dev_err (dev,"Cannot initialize the chip.\n" ); +return ret; + } + + ret =bq257xx_power_supply_init (pdata, &psy_cfg, dev); +if (ret) +return ret; + +platform_set_drvdata (pdev, pdata); + +if (bq->client->irq) { + ret =devm_request_threaded_irq (dev, bq->client->irq,NULL , + bq257xx_irq_handler_thread, +IRQF_TRIGGER_RISING | +IRQF_TRIGGER_FALLING | +IRQF_ONESHOT , +dev_name (&bq->client->dev), pdata); +if (ret <0 ) { +dev_err (dev,"get irq fail: %d\n" , ret); +return ret; + } + } + +return ret; +} + +static void bq257xx_charger_shutdown (struct platform_device *pdev) +{ +struct bq257xx_chg *pdata =platform_get_drvdata (pdev); + + pdata->chip->bq257xx_hw_shutdown (pdata); +} + +static struct platform_driver bq257xx_chg_driver = { + .driver = {
drivers/power/supply/bq257xx_charger.c line 811
Quoted 10 lines
drivers/power/supply/bq257xx_charger.c new file +10
-0+ .name = "bq257xx-charger", + }, + .probe = bq257xx_charger_probe, + .shutdown = bq257xx_charger_shutdown, +}; +module_platform_driver (bq257xx_chg_driver); + +MODULE_DESCRIPTION ("bq257xx charger driver" ); +MODULE_AUTHOR ("Chris Morgan <[email protected]>" ); +MODULE_LICENSE ("GPL" );
Greetings,
-- Sebastian
RFC 4/5 regulator: bq257xx: Add bq257xx boost regulator driver
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add support for the boost regulator found in the Texas Instruments BQ25703. The boost regulator is capable of outputting between 4.48 and 20.8 volts and between 0 and 6.35 amps.
--- drivers/regulator/Kconfig | 8 ++ drivers/regulator/Makefile | 1 + drivers/regulator/bq257xx-regulator.c | 195 ++++++++++++++++++++++++++ 3 files changed, 204 insertions(+) create mode 100644 drivers/regulator/bq257xx-regulator.c
drivers/regulator/Kconfig +8 -0
@@ -286,6 +286,14 @@ config REGULATOR_BD96801 This driver can also be built as a module. If so, the module will be called bd96801-regulator. +config REGULATOR_BQ257XX + tristate "TI BQ257XX regulator family" + depends on MFD_BQ257XX + depends on GPIOLIB || COMPILE_TEST + help + Say Y to enable support for the boost regulator function of + the BQ257XX family of charger circuits. + config REGULATOR_CPCAP tristate "Motorola CPCAP regulator" depends on MFD_CPCAP
drivers/regulator/Makefile +1 -0
@@ -37,6 +37,7 @@ obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o obj-$(CONFIG_REGULATOR_BD957XMUF) += bd9576-regulator.o +obj-$(CONFIG_REGULATOR_BQ257XX) += bq257xx-regulator.o obj-$(CONFIG_REGULATOR_DA903X) += da903x-regulator.o obj-$(CONFIG_REGULATOR_BD96801) += bd96801-regulator.o obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
drivers/regulator/bq257xx-regulator.c new file +195 -0
195 lines not on this page · raw message
Signature · 1 line
2.34.1
RFC 5/5 arm64: dts: rockchip: Add USB and charger to Gameforce Ace
In reply to Chris MorganFrom: Chris Morgan <[email protected]>
Add support for the BQ25703 charger manager and boost regulator to the Gameforce Ace. This also allows us to add the USB Type-C port manager which has a dependency on the boost regulator.
This specific patch has a dependency on the following series:
https://lore.kernel.org/linux-rockchip/[email protected]/
--- .../dts/rockchip/rk3588s-gameforce-ace.dts | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+)
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +120 -0
@@ -575,6 +575,56 @@ &i2c6 { pinctrl-0 = <&i2c6m3_xfer>; status = "okay"; + fusb302: typec-portc@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PC7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&usbc0_int>; + pinctrl-names = "default"; + vbus-supply = <&usb_otg_vbus>; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C"; + op-sink-microwatt = <1000000>; + power-role = "dual"; + self-powered; + sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) + PDO_FIXED(9000, 3000, PDO_FIXED_USB_COMM) + PDO_FIXED(12000, 3000, PDO_FIXED_USB_COMM)>; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usbc0_orien_sw: endpoint { + remote-endpoint = <&usbdp_phy0_orientation_switch>; + }; + }; + + port@1 { + reg = <1>; + usbc0_role_sw: endpoint { + remote-endpoint = <&dwc3_0_role_switch>; + }; + }; + + port@2 { + reg = <2>; + dp_altmode_mux: endpoint { + remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; + }; + }; + }; + }; + }; + rtc_hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>;
@@ -603,8 +653,40 @@ cw2015@62 { 0x2F 0x00 0x64 0xA5 0xB5 0x1C 0xF0 0x49>; cellwise,monitor-interval-ms = <5000>; monitored-battery = <&battery>; + power-supplies = <&bq25703>; status = "okay"; }; + + bq25703: bq25703@6b { + compatible = "ti,bq25703a"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&charger_int_h>; + pinctrl-names = "default"; + power-supplies = <&fusb302>; + ti,charge-current = <2500000>; + ti,current-limit = <5000000>; + ti,max-charge-voltage = <8750000>; + ti,minimum-sys-voltage = <7400000>; + + regulators { + usb_otg_vbus: usb-otg-vbus { + enable-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&boost_enable_h>; + pinctrl-names = "default"; + regulator-max-microamp = <960000>; + regulator-max-microvolt = <5088000>; + regulator-min-microamp = <512000>; + regulator-min-microvolt = <4992000>; + regulator-name = "usb_otg_vbus"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; }; &i2c7 {
@@ -1235,3 +1317,41 @@ bluetooth { shutdown-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_HIGH>; }; }; + +&usb_host0_xhci { + usb-role-switch; + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + dwc3_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + +&usbdp_phy0 { + mode-switch; + orientation-switch; + sbu1-dc-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>; + sbu2-dc-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>; + rockchip,dp-lane-mux = <2 3>; + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + usbdp_phy0_orientation_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_orien_sw>; + }; + + usbdp_phy0_dp_altmode_mux: endpoint@1 { + reg = <1>; + remote-endpoint = <&dp_altmode_mux>; + }; + }; +};
Signature · 1 line
2.34.1
Re: [RFC 5/5] arm64: dts: rockchip: Add USB and charger to Gameforce Ace
Quoted 19 lines · Chris Morgan
From: Chris Morgan <[email protected]>
Add support for the BQ25703 charger manager and boost regulator to the Gameforce Ace. This also allows us to add the USB Type-C port manager which has a dependency on the boost regulator.
This specific patch has a dependency on the following series:
https://lore.kernel.org/linux-rockchip/[email protected]/Signed-off-by Chris Morgan <[email protected]>--- .../dts/rockchip/rk3588s-gameforce-ace.dts | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+)arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +0
-0
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts &i2c6 { · line 578
Quoted 4 lines
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +1
-0@@ -575,6 +575,56 @@ &i2c6 { pinctrl-0 = <&i2c6m3_xfer>; status = "okay"; + fusb302: typec-portc@22 {
typec@
Quoted 53 lines
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +49
-0+ compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PC7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&usbc0_int>; + pinctrl-names = "default"; + vbus-supply = <&usb_otg_vbus>; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C"; + op-sink-microwatt = <1000000>; + power-role = "dual"; + self-powered; + sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) + PDO_FIXED(9000, 3000, PDO_FIXED_USB_COMM) + PDO_FIXED(12000, 3000, PDO_FIXED_USB_COMM)>; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usbc0_orien_sw: endpoint { + remote-endpoint = <&usbdp_phy0_orientation_switch>; + }; + }; + + port@1 { + reg = <1>; + usbc0_role_sw: endpoint { + remote-endpoint = <&dwc3_0_role_switch>; + }; + }; + + port@2 { + reg = <2>; + dp_altmode_mux: endpoint { + remote-endpoint = <&usbdp_phy0_dp_altmode_mux>; + }; + }; + }; + }; + }; + rtc_hym8563: rtc@51 { compatible = "haoyu,hym8563"; reg = <0x51>;
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts cw2015@62 { · line 660
Quoted 8 lines
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +3
-0@@ -603,8 +653,40 @@ cw2015@62 { 0x2F 0x00 0x64 0xA5 0xB5 0x1C 0xF0 0x49>; cellwise,monitor-interval-ms = <5000>; monitored-battery = <&battery>; + power-supplies = <&bq25703>; status = "okay"; }; + + bq25703: bq25703@6b {
Node names should be generic. See also an explanation and list of examples (not exhaustive) in DT specification:
https://devicetree-specification.readthedocs.io/en/latest/chapter2-devicetree-basics.html#generic-names-recommendation
e.g. charger@
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts cw2015@62 { · line 667
Quoted 7 lines
arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +7
-0+ compatible = "ti,bq25703a"; + reg = <0x6b>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD5 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&charger_int_h>; + pinctrl-names = "default"; + power-supplies = <&fusb302>;
Best regards,
Krzysztof