^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Driver for the TI bq24190 battery charger.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Mark A. Greer <mgreer@animalcreek.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/of_irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/power/bq24190_charger.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/regulator/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/workqueue.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/extcon-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define BQ24190_MANUFACTURER "Texas Instruments"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define BQ24190_REG_ISC 0x00 /* Input Source Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define BQ24190_REG_ISC_EN_HIZ_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define BQ24190_REG_ISC_EN_HIZ_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define BQ24190_REG_ISC_VINDPM_MASK (BIT(6) | BIT(5) | BIT(4) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) BIT(3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define BQ24190_REG_ISC_VINDPM_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define BQ24190_REG_ISC_IINLIM_MASK (BIT(2) | BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define BQ24190_REG_ISC_IINLIM_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define BQ24190_REG_POC 0x01 /* Power-On Configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define BQ24190_REG_POC_RESET_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define BQ24190_REG_POC_RESET_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define BQ24190_REG_POC_WDT_RESET_MASK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define BQ24190_REG_POC_WDT_RESET_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define BQ24190_REG_POC_CHG_CONFIG_MASK (BIT(5) | BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define BQ24190_REG_POC_CHG_CONFIG_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define BQ24190_REG_POC_CHG_CONFIG_DISABLE 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define BQ24190_REG_POC_CHG_CONFIG_CHARGE 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define BQ24190_REG_POC_CHG_CONFIG_OTG 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define BQ24190_REG_POC_CHG_CONFIG_OTG_ALT 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define BQ24190_REG_POC_SYS_MIN_MASK (BIT(3) | BIT(2) | BIT(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define BQ24190_REG_POC_SYS_MIN_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define BQ24190_REG_POC_SYS_MIN_MIN 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define BQ24190_REG_POC_SYS_MIN_MAX 3700
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define BQ24190_REG_POC_BOOST_LIM_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define BQ24190_REG_POC_BOOST_LIM_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define BQ24190_REG_CCC 0x02 /* Charge Current Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define BQ24190_REG_CCC_ICHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) BIT(4) | BIT(3) | BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define BQ24190_REG_CCC_ICHG_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define BQ24190_REG_CCC_FORCE_20PCT_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define BQ24190_REG_CCC_FORCE_20PCT_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define BQ24190_REG_PCTCC 0x03 /* Pre-charge/Termination Current Cntl */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define BQ24190_REG_PCTCC_IPRECHG_MASK (BIT(7) | BIT(6) | BIT(5) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define BQ24190_REG_PCTCC_IPRECHG_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define BQ24190_REG_PCTCC_IPRECHG_MIN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define BQ24190_REG_PCTCC_IPRECHG_MAX 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define BQ24190_REG_PCTCC_ITERM_MASK (BIT(3) | BIT(2) | BIT(1) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define BQ24190_REG_PCTCC_ITERM_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define BQ24190_REG_PCTCC_ITERM_MIN 128
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define BQ24190_REG_PCTCC_ITERM_MAX 2048
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define BQ24190_REG_CVC 0x04 /* Charge Voltage Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define BQ24190_REG_CVC_VREG_MASK (BIT(7) | BIT(6) | BIT(5) | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) BIT(4) | BIT(3) | BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define BQ24190_REG_CVC_VREG_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define BQ24190_REG_CVC_BATLOWV_MASK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define BQ24190_REG_CVC_BATLOWV_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define BQ24190_REG_CVC_VRECHG_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define BQ24190_REG_CVC_VRECHG_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define BQ24190_REG_CTTC 0x05 /* Charge Term/Timer Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define BQ24190_REG_CTTC_EN_TERM_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define BQ24190_REG_CTTC_EN_TERM_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define BQ24190_REG_CTTC_TERM_STAT_MASK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define BQ24190_REG_CTTC_TERM_STAT_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define BQ24190_REG_CTTC_WATCHDOG_MASK (BIT(5) | BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define BQ24190_REG_CTTC_WATCHDOG_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define BQ24190_REG_CTTC_EN_TIMER_MASK BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define BQ24190_REG_CTTC_EN_TIMER_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define BQ24190_REG_CTTC_CHG_TIMER_MASK (BIT(2) | BIT(1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define BQ24190_REG_CTTC_CHG_TIMER_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define BQ24190_REG_CTTC_JEITA_ISET_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define BQ24190_REG_CTTC_JEITA_ISET_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define BQ24190_REG_ICTRC 0x06 /* IR Comp/Thermal Regulation Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define BQ24190_REG_ICTRC_BAT_COMP_MASK (BIT(7) | BIT(6) | BIT(5))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define BQ24190_REG_ICTRC_BAT_COMP_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define BQ24190_REG_ICTRC_VCLAMP_MASK (BIT(4) | BIT(3) | BIT(2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define BQ24190_REG_ICTRC_VCLAMP_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define BQ24190_REG_ICTRC_TREG_MASK (BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define BQ24190_REG_ICTRC_TREG_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define BQ24190_REG_MOC 0x07 /* Misc. Operation Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define BQ24190_REG_MOC_DPDM_EN_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define BQ24190_REG_MOC_DPDM_EN_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define BQ24190_REG_MOC_TMR2X_EN_MASK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define BQ24190_REG_MOC_TMR2X_EN_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define BQ24190_REG_MOC_BATFET_DISABLE_MASK BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define BQ24190_REG_MOC_BATFET_DISABLE_SHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define BQ24190_REG_MOC_JEITA_VSET_MASK BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define BQ24190_REG_MOC_JEITA_VSET_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define BQ24190_REG_MOC_INT_MASK_MASK (BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define BQ24190_REG_MOC_INT_MASK_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define BQ24190_REG_SS 0x08 /* System Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define BQ24190_REG_SS_VBUS_STAT_MASK (BIT(7) | BIT(6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define BQ24190_REG_SS_VBUS_STAT_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define BQ24190_REG_SS_CHRG_STAT_MASK (BIT(5) | BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define BQ24190_REG_SS_CHRG_STAT_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define BQ24190_REG_SS_DPM_STAT_MASK BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define BQ24190_REG_SS_DPM_STAT_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define BQ24190_REG_SS_PG_STAT_MASK BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define BQ24190_REG_SS_PG_STAT_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define BQ24190_REG_SS_THERM_STAT_MASK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define BQ24190_REG_SS_THERM_STAT_SHIFT 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define BQ24190_REG_SS_VSYS_STAT_MASK BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define BQ24190_REG_SS_VSYS_STAT_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define BQ24190_REG_F 0x09 /* Fault */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define BQ24190_REG_F_WATCHDOG_FAULT_MASK BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define BQ24190_REG_F_WATCHDOG_FAULT_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define BQ24190_REG_F_BOOST_FAULT_MASK BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define BQ24190_REG_F_BOOST_FAULT_SHIFT 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define BQ24190_REG_F_CHRG_FAULT_MASK (BIT(5) | BIT(4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define BQ24190_REG_F_CHRG_FAULT_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define BQ24190_REG_F_BAT_FAULT_MASK BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define BQ24190_REG_F_BAT_FAULT_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define BQ24190_REG_F_NTC_FAULT_MASK (BIT(2) | BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define BQ24190_REG_F_NTC_FAULT_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define BQ24190_REG_VPRS 0x0A /* Vendor/Part/Revision Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define BQ24190_REG_VPRS_PN_MASK (BIT(5) | BIT(4) | BIT(3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define BQ24190_REG_VPRS_PN_SHIFT 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define BQ24190_REG_VPRS_PN_24190 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define BQ24190_REG_VPRS_PN_24192 0x5 /* Also 24193, 24196 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define BQ24190_REG_VPRS_PN_24192I 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define BQ24190_REG_VPRS_TS_PROFILE_MASK BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define BQ24190_REG_VPRS_TS_PROFILE_SHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define BQ24190_REG_VPRS_DEV_REG_MASK (BIT(1) | BIT(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define BQ24190_REG_VPRS_DEV_REG_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * The FAULT register is latched by the bq24190 (except for NTC_FAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * so the first read after a fault returns the latched value and subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * reads return the current value. In order to return the fault status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * to the user, have the interrupt handler save the reg's value and retrieve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) * it in the appropriate health/status routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct bq24190_dev_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct extcon_dev *edev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct power_supply *charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct power_supply *battery;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct delayed_work input_current_limit_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) char model_name[I2C_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) bool initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) bool irq_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) u16 sys_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) u16 iprechg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) u16 iterm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct mutex f_reg_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u8 f_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u8 ss_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 watchdog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static const unsigned int bq24190_usb_extcon_cable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) EXTCON_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) EXTCON_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) * The tables below provide a 2-way mapping for the value that goes in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) * the register field and the real-world value that it represents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * The index of the array is the value that goes in the register; the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * number at that index in the array is the real-world value that it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * represents.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* REG00[2:0] (IINLIM) in uAh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static const int bq24190_isc_iinlim_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 100000, 150000, 500000, 900000, 1200000, 1500000, 2000000, 3000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* REG02[7:2] (ICHG) in uAh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static const int bq24190_ccc_ichg_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 512000, 576000, 640000, 704000, 768000, 832000, 896000, 960000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 1024000, 1088000, 1152000, 1216000, 1280000, 1344000, 1408000, 1472000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 1536000, 1600000, 1664000, 1728000, 1792000, 1856000, 1920000, 1984000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 2048000, 2112000, 2176000, 2240000, 2304000, 2368000, 2432000, 2496000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 2560000, 2624000, 2688000, 2752000, 2816000, 2880000, 2944000, 3008000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 3072000, 3136000, 3200000, 3264000, 3328000, 3392000, 3456000, 3520000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 3584000, 3648000, 3712000, 3776000, 3840000, 3904000, 3968000, 4032000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 4096000, 4160000, 4224000, 4288000, 4352000, 4416000, 4480000, 4544000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) /* REG04[7:2] (VREG) in uV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static const int bq24190_cvc_vreg_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 3504000, 3520000, 3536000, 3552000, 3568000, 3584000, 3600000, 3616000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 3632000, 3648000, 3664000, 3680000, 3696000, 3712000, 3728000, 3744000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 3760000, 3776000, 3792000, 3808000, 3824000, 3840000, 3856000, 3872000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 3888000, 3904000, 3920000, 3936000, 3952000, 3968000, 3984000, 4000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 4016000, 4032000, 4048000, 4064000, 4080000, 4096000, 4112000, 4128000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 4144000, 4160000, 4176000, 4192000, 4208000, 4224000, 4240000, 4256000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 4272000, 4288000, 4304000, 4320000, 4336000, 4352000, 4368000, 4384000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 4400000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* REG06[1:0] (TREG) in tenths of degrees Celsius */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static const int bq24190_ictrc_treg_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 600, 800, 1000, 1200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) * Return the index in 'tbl' of greatest value that is less than or equal to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * 'val'. The index range returned is 0 to 'tbl_size' - 1. Assumes that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * the values in 'tbl' are sorted from smallest to largest and 'tbl_size'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * is less than 2^8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static u8 bq24190_find_idx(const int tbl[], int tbl_size, int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) for (i = 1; i < tbl_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (v < tbl[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* Basic driver I/O routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int bq24190_read(struct bq24190_dev_info *bdi, u8 reg, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) ret = i2c_smbus_read_byte_data(bdi->client, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) *data = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static int bq24190_write(struct bq24190_dev_info *bdi, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) return i2c_smbus_write_byte_data(bdi->client, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static int bq24190_read_mask(struct bq24190_dev_info *bdi, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) u8 mask, u8 shift, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ret = bq24190_read(bdi, reg, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) v &= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) v >>= shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *data = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int bq24190_write_mask(struct bq24190_dev_info *bdi, u8 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) u8 mask, u8 shift, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) ret = bq24190_read(bdi, reg, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) v &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) v |= ((data << shift) & mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return bq24190_write(bdi, reg, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int bq24190_get_field_val(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u8 reg, u8 mask, u8 shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) const int tbl[], int tbl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) int *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ret = bq24190_read_mask(bdi, reg, mask, shift, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) v = (v >= tbl_size) ? (tbl_size - 1) : v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) *val = tbl[v];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int bq24190_set_field_val(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u8 reg, u8 mask, u8 shift,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) const int tbl[], int tbl_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) u8 idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) idx = bq24190_find_idx(tbl, tbl_size, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return bq24190_write_mask(bdi, reg, mask, shift, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #ifdef CONFIG_SYSFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * There are a numerous options that are configurable on the bq24190
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * that go well beyond what the power_supply properties provide access to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * Provide sysfs access to them so they can be examined and possibly modified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * on the fly. They will be provided for the charger power_supply object only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * and will be prefixed by 'f_' to make them easier to recognize.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) #define BQ24190_SYSFS_FIELD(_name, r, f, m, store) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) .attr = __ATTR(f_##_name, m, bq24190_sysfs_show, store), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) .reg = BQ24190_REG_##r, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) .mask = BQ24190_REG_##r##_##f##_MASK, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) .shift = BQ24190_REG_##r##_##f##_SHIFT, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) #define BQ24190_SYSFS_FIELD_RW(_name, r, f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) BQ24190_SYSFS_FIELD(_name, r, f, S_IWUSR | S_IRUGO, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) bq24190_sysfs_store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) #define BQ24190_SYSFS_FIELD_RO(_name, r, f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) BQ24190_SYSFS_FIELD(_name, r, f, S_IRUGO, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static ssize_t bq24190_sysfs_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct device_attribute *attr, char *buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) static ssize_t bq24190_sysfs_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct device_attribute *attr, const char *buf, size_t count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) struct bq24190_sysfs_field_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct device_attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u8 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) u8 shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) /* On i386 ptrace-abi.h defines SS that breaks the macro calls below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) #undef SS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) static struct bq24190_sysfs_field_info bq24190_sysfs_field_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* sysfs name reg field in reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) BQ24190_SYSFS_FIELD_RW(en_hiz, ISC, EN_HIZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) BQ24190_SYSFS_FIELD_RW(vindpm, ISC, VINDPM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) BQ24190_SYSFS_FIELD_RW(iinlim, ISC, IINLIM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) BQ24190_SYSFS_FIELD_RW(chg_config, POC, CHG_CONFIG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) BQ24190_SYSFS_FIELD_RW(sys_min, POC, SYS_MIN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) BQ24190_SYSFS_FIELD_RW(boost_lim, POC, BOOST_LIM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) BQ24190_SYSFS_FIELD_RW(ichg, CCC, ICHG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) BQ24190_SYSFS_FIELD_RW(force_20_pct, CCC, FORCE_20PCT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) BQ24190_SYSFS_FIELD_RW(iprechg, PCTCC, IPRECHG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) BQ24190_SYSFS_FIELD_RW(iterm, PCTCC, ITERM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) BQ24190_SYSFS_FIELD_RW(vreg, CVC, VREG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) BQ24190_SYSFS_FIELD_RW(batlowv, CVC, BATLOWV),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) BQ24190_SYSFS_FIELD_RW(vrechg, CVC, VRECHG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) BQ24190_SYSFS_FIELD_RW(en_term, CTTC, EN_TERM),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) BQ24190_SYSFS_FIELD_RW(term_stat, CTTC, TERM_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) BQ24190_SYSFS_FIELD_RO(watchdog, CTTC, WATCHDOG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) BQ24190_SYSFS_FIELD_RW(en_timer, CTTC, EN_TIMER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) BQ24190_SYSFS_FIELD_RW(chg_timer, CTTC, CHG_TIMER),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) BQ24190_SYSFS_FIELD_RW(jeta_iset, CTTC, JEITA_ISET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) BQ24190_SYSFS_FIELD_RW(bat_comp, ICTRC, BAT_COMP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) BQ24190_SYSFS_FIELD_RW(vclamp, ICTRC, VCLAMP),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) BQ24190_SYSFS_FIELD_RW(treg, ICTRC, TREG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) BQ24190_SYSFS_FIELD_RW(dpdm_en, MOC, DPDM_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) BQ24190_SYSFS_FIELD_RW(tmr2x_en, MOC, TMR2X_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) BQ24190_SYSFS_FIELD_RW(batfet_disable, MOC, BATFET_DISABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) BQ24190_SYSFS_FIELD_RW(jeita_vset, MOC, JEITA_VSET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) BQ24190_SYSFS_FIELD_RO(int_mask, MOC, INT_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) BQ24190_SYSFS_FIELD_RO(vbus_stat, SS, VBUS_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) BQ24190_SYSFS_FIELD_RO(chrg_stat, SS, CHRG_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) BQ24190_SYSFS_FIELD_RO(dpm_stat, SS, DPM_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) BQ24190_SYSFS_FIELD_RO(pg_stat, SS, PG_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) BQ24190_SYSFS_FIELD_RO(therm_stat, SS, THERM_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) BQ24190_SYSFS_FIELD_RO(vsys_stat, SS, VSYS_STAT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) BQ24190_SYSFS_FIELD_RO(watchdog_fault, F, WATCHDOG_FAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) BQ24190_SYSFS_FIELD_RO(boost_fault, F, BOOST_FAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) BQ24190_SYSFS_FIELD_RO(chrg_fault, F, CHRG_FAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) BQ24190_SYSFS_FIELD_RO(bat_fault, F, BAT_FAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) BQ24190_SYSFS_FIELD_RO(ntc_fault, F, NTC_FAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) BQ24190_SYSFS_FIELD_RO(pn, VPRS, PN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) BQ24190_SYSFS_FIELD_RO(ts_profile, VPRS, TS_PROFILE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) BQ24190_SYSFS_FIELD_RO(dev_reg, VPRS, DEV_REG),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static struct attribute *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) bq24190_sysfs_attrs[ARRAY_SIZE(bq24190_sysfs_field_tbl) + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ATTRIBUTE_GROUPS(bq24190_sysfs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static void bq24190_sysfs_init_attrs(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) for (i = 0; i < limit; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) bq24190_sysfs_attrs[i] = &bq24190_sysfs_field_tbl[i].attr.attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) bq24190_sysfs_attrs[limit] = NULL; /* Has additional entry for this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static struct bq24190_sysfs_field_info *bq24190_sysfs_field_lookup(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int i, limit = ARRAY_SIZE(bq24190_sysfs_field_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) for (i = 0; i < limit; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!strcmp(name, bq24190_sysfs_field_tbl[i].attr.attr.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (i >= limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return &bq24190_sysfs_field_tbl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) static ssize_t bq24190_sysfs_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct power_supply *psy = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct bq24190_sysfs_field_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ssize_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) info = bq24190_sysfs_field_lookup(attr->attr.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) ret = bq24190_read_mask(bdi, info->reg, info->mask, info->shift, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) count = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) count = scnprintf(buf, PAGE_SIZE, "%hhx\n", v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static ssize_t bq24190_sysfs_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct device_attribute *attr, const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct power_supply *psy = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct bq24190_sysfs_field_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) info = bq24190_sysfs_field_lookup(attr->attr.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) if (!info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ret = kstrtou8(buf, 0, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = bq24190_write_mask(bdi, info->reg, info->mask, info->shift, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) count = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) #ifdef CONFIG_REGULATOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static int bq24190_set_charge_mode(struct regulator_dev *dev, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) BQ24190_REG_POC_CHG_CONFIG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) BQ24190_REG_POC_CHG_CONFIG_SHIFT, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static int bq24190_vbus_enable(struct regulator_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_OTG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static int bq24190_vbus_disable(struct regulator_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return bq24190_set_charge_mode(dev, BQ24190_REG_POC_CHG_CONFIG_CHARGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) static int bq24190_vbus_is_enabled(struct regulator_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) struct bq24190_dev_info *bdi = rdev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) BQ24190_REG_POC_CHG_CONFIG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) BQ24190_REG_POC_CHG_CONFIG_SHIFT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return (val == BQ24190_REG_POC_CHG_CONFIG_OTG ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) val == BQ24190_REG_POC_CHG_CONFIG_OTG_ALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static const struct regulator_ops bq24190_vbus_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) .enable = bq24190_vbus_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) .disable = bq24190_vbus_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) .is_enabled = bq24190_vbus_is_enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static const struct regulator_desc bq24190_vbus_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) .name = "usb_otg_vbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) .of_match = "usb-otg-vbus",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) .type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) .ops = &bq24190_vbus_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) .fixed_uV = 5000000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) .n_voltages = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) static const struct regulator_init_data bq24190_vbus_init_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) .constraints = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) .valid_ops_mask = REGULATOR_CHANGE_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) struct bq24190_platform_data *pdata = bdi->dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct regulator_config cfg = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) struct regulator_dev *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) cfg.dev = bdi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (pdata && pdata->regulator_init_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) cfg.init_data = pdata->regulator_init_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) cfg.init_data = &bq24190_vbus_init_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) cfg.driver_data = bdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) reg = devm_regulator_register(bdi->dev, &bq24190_vbus_desc, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (IS_ERR(reg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ret = PTR_ERR(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) dev_err(bdi->dev, "Can't register regulator: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) static int bq24190_register_vbus_regulator(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) static int bq24190_set_config(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) ret = bq24190_read(bdi, BQ24190_REG_CTTC, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) bdi->watchdog = ((v & BQ24190_REG_CTTC_WATCHDOG_MASK) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) BQ24190_REG_CTTC_WATCHDOG_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * According to the "Host Mode and default Mode" section of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * manual, a write to any register causes the bq24190 to switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * from default mode to host mode. It will switch back to default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * mode after a WDT timeout unless the WDT is turned off as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * So, by simply turning off the WDT, we accomplish both with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * same write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) v &= ~BQ24190_REG_CTTC_WATCHDOG_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ret = bq24190_write(bdi, BQ24190_REG_CTTC, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (bdi->sys_min) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) v = bdi->sys_min / 100 - 30; // manual section 9.5.1.2, table 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) BQ24190_REG_POC_SYS_MIN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) BQ24190_REG_POC_SYS_MIN_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (bdi->iprechg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) v = bdi->iprechg / 128 - 1; // manual section 9.5.1.4, table 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) BQ24190_REG_PCTCC_IPRECHG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) BQ24190_REG_PCTCC_IPRECHG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (bdi->iterm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) v = bdi->iterm / 128 - 1; // manual section 9.5.1.4, table 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ret = bq24190_write_mask(bdi, BQ24190_REG_PCTCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) BQ24190_REG_PCTCC_ITERM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) BQ24190_REG_PCTCC_ITERM_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) static int bq24190_register_reset(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) int ret, limit = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) * This prop. can be passed on device instantiation from platform code:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * struct property_entry pe[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * { PROPERTY_ENTRY_BOOL("disable-reset"), ... };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * struct i2c_board_info bi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * { .type = "bq24190", .addr = 0x6b, .properties = pe, .irq = irq };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * struct i2c_adapter ad = { ... };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * i2c_add_adapter(&ad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * i2c_new_client_device(&ad, &bi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (device_property_read_bool(bdi->dev, "disable-reset"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Reset the registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) ret = bq24190_write_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) BQ24190_REG_POC_RESET_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) BQ24190_REG_POC_RESET_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /* Reset bit will be cleared by hardware so poll until it is */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) BQ24190_REG_POC_RESET_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) BQ24190_REG_POC_RESET_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (v == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) } while (--limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* Charger power supply property routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) static int bq24190_charger_get_charge_type(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int type, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ret = bq24190_read_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) BQ24190_REG_POC_CHG_CONFIG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) BQ24190_REG_POC_CHG_CONFIG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /* If POC[CHG_CONFIG] (REG01[5:4]) == 0, charge is disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (!v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) type = POWER_SUPPLY_CHARGE_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) BQ24190_REG_CCC_FORCE_20PCT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) type = (v) ? POWER_SUPPLY_CHARGE_TYPE_TRICKLE :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) POWER_SUPPLY_CHARGE_TYPE_FAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) val->intval = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) static int bq24190_charger_set_charge_type(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) u8 chg_config, force_20pct, en_term;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) * According to the "Termination when REG02[0] = 1" section of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * the bq24190 manual, the trickle charge could be less than the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) * termination current so it recommends turning off the termination
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) * function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) * Note: AFAICT from the datasheet, the user will have to manually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * turn off the charging when in 20% mode. If its not turned off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) * there could be battery damage. So, use this mode at your own risk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) switch (val->intval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) case POWER_SUPPLY_CHARGE_TYPE_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) chg_config = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) case POWER_SUPPLY_CHARGE_TYPE_TRICKLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) chg_config = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) force_20pct = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) en_term = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) case POWER_SUPPLY_CHARGE_TYPE_FAST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) chg_config = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) force_20pct = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) en_term = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (chg_config) { /* Enabling the charger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ret = bq24190_write_mask(bdi, BQ24190_REG_CCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) BQ24190_REG_CCC_FORCE_20PCT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) BQ24190_REG_CCC_FORCE_20PCT_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) force_20pct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) ret = bq24190_write_mask(bdi, BQ24190_REG_CTTC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) BQ24190_REG_CTTC_EN_TERM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) BQ24190_REG_CTTC_EN_TERM_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) en_term);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return bq24190_write_mask(bdi, BQ24190_REG_POC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) BQ24190_REG_POC_CHG_CONFIG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) BQ24190_REG_POC_CHG_CONFIG_SHIFT, chg_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) static int bq24190_charger_get_health(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) int health;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) mutex_lock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) v = bdi->f_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) mutex_unlock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (v & BQ24190_REG_F_NTC_FAULT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) switch (v >> BQ24190_REG_F_NTC_FAULT_SHIFT & 0x7) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case 0x1: /* TS1 Cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) case 0x3: /* TS2 Cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) case 0x5: /* Both Cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) health = POWER_SUPPLY_HEALTH_COLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) case 0x2: /* TS1 Hot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case 0x4: /* TS2 Hot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) case 0x6: /* Both Hot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) health = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) health = POWER_SUPPLY_HEALTH_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) } else if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) } else if (v & BQ24190_REG_F_CHRG_FAULT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) switch (v >> BQ24190_REG_F_CHRG_FAULT_SHIFT & 0x3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) case 0x1: /* Input Fault (VBUS OVP or VBAT<VBUS<3.8V) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) * This could be over-voltage or under-voltage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * and there's no way to tell which. Instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * of looking foolish and returning 'OVERVOLTAGE'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * when its really under-voltage, just return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * 'UNSPEC_FAILURE'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) health = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) case 0x2: /* Thermal Shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) health = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case 0x3: /* Charge Safety Timer Expiration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) health = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) default: /* prevent compiler warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) health = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) } else if (v & BQ24190_REG_F_BOOST_FAULT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) * This could be over-current or over-voltage but there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * no way to tell which. Return 'OVERVOLTAGE' since there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * isn't an 'OVERCURRENT' value defined that we can return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) * even if it was over-current.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) health = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) val->intval = health;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) static int bq24190_charger_get_online(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) u8 pg_stat, batfet_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret = bq24190_read_mask(bdi, BQ24190_REG_SS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) BQ24190_REG_SS_PG_STAT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) BQ24190_REG_SS_PG_STAT_SHIFT, &pg_stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) BQ24190_REG_MOC_BATFET_DISABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) val->intval = pg_stat && !batfet_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) const union power_supply_propval *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) union power_supply_propval *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) union power_supply_propval *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) const union power_supply_propval *val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static int bq24190_charger_set_online(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return bq24190_battery_set_online(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) static int bq24190_charger_get_status(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return bq24190_battery_get_status(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static int bq24190_charger_get_temp_alert_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return bq24190_battery_get_temp_alert_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static int bq24190_charger_set_temp_alert_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return bq24190_battery_set_temp_alert_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static int bq24190_charger_get_precharge(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) BQ24190_REG_PCTCC_IPRECHG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) BQ24190_REG_PCTCC_IPRECHG_SHIFT, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) val->intval = ++v * 128 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) static int bq24190_charger_get_charge_term(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ret = bq24190_read_mask(bdi, BQ24190_REG_PCTCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) BQ24190_REG_PCTCC_ITERM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) BQ24190_REG_PCTCC_ITERM_SHIFT, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) val->intval = ++v * 128 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) static int bq24190_charger_get_current(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) int curr, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ret = bq24190_get_field_val(bdi, BQ24190_REG_CCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) bq24190_ccc_ichg_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) ARRAY_SIZE(bq24190_ccc_ichg_values), &curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) BQ24190_REG_CCC_FORCE_20PCT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) /* If FORCE_20PCT is enabled, then current is 20% of ICHG value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) curr /= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) val->intval = curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static int bq24190_charger_get_current_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) int idx = ARRAY_SIZE(bq24190_ccc_ichg_values) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) val->intval = bq24190_ccc_ichg_values[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) static int bq24190_charger_set_current(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) int ret, curr = val->intval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ret = bq24190_read_mask(bdi, BQ24190_REG_CCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) BQ24190_REG_CCC_FORCE_20PCT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) BQ24190_REG_CCC_FORCE_20PCT_SHIFT, &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* If FORCE_20PCT is enabled, have to multiply value passed in by 5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) curr *= 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return bq24190_set_field_val(bdi, BQ24190_REG_CCC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) BQ24190_REG_CCC_ICHG_MASK, BQ24190_REG_CCC_ICHG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) bq24190_ccc_ichg_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ARRAY_SIZE(bq24190_ccc_ichg_values), curr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static int bq24190_charger_get_voltage(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) int voltage, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ret = bq24190_get_field_val(bdi, BQ24190_REG_CVC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) bq24190_cvc_vreg_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ARRAY_SIZE(bq24190_cvc_vreg_values), &voltage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) val->intval = voltage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static int bq24190_charger_get_voltage_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) int idx = ARRAY_SIZE(bq24190_cvc_vreg_values) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) val->intval = bq24190_cvc_vreg_values[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static int bq24190_charger_set_voltage(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return bq24190_set_field_val(bdi, BQ24190_REG_CVC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) BQ24190_REG_CVC_VREG_MASK, BQ24190_REG_CVC_VREG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) bq24190_cvc_vreg_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) ARRAY_SIZE(bq24190_cvc_vreg_values), val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static int bq24190_charger_get_iinlimit(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int iinlimit, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) ret = bq24190_get_field_val(bdi, BQ24190_REG_ISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) BQ24190_REG_ISC_IINLIM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) BQ24190_REG_ISC_IINLIM_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) bq24190_isc_iinlim_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ARRAY_SIZE(bq24190_isc_iinlim_values), &iinlimit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) val->intval = iinlimit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static int bq24190_charger_set_iinlimit(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) return bq24190_set_field_val(bdi, BQ24190_REG_ISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) BQ24190_REG_ISC_IINLIM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) BQ24190_REG_ISC_IINLIM_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) bq24190_isc_iinlim_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ARRAY_SIZE(bq24190_isc_iinlim_values), val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static int bq24190_charger_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) enum power_supply_property psp, union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) dev_dbg(bdi->dev, "prop: %d\n", psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) case POWER_SUPPLY_PROP_CHARGE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) ret = bq24190_charger_get_charge_type(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) ret = bq24190_charger_get_health(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) ret = bq24190_charger_get_online(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ret = bq24190_charger_get_status(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) ret = bq24190_charger_get_temp_alert_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) ret = bq24190_charger_get_precharge(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ret = bq24190_charger_get_charge_term(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) ret = bq24190_charger_get_current(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ret = bq24190_charger_get_current_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) ret = bq24190_charger_get_voltage(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) ret = bq24190_charger_get_voltage_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ret = bq24190_charger_get_iinlimit(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) case POWER_SUPPLY_PROP_SCOPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) case POWER_SUPPLY_PROP_MODEL_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) val->strval = bdi->model_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) case POWER_SUPPLY_PROP_MANUFACTURER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) val->strval = BQ24190_MANUFACTURER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) static int bq24190_charger_set_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev_dbg(bdi->dev, "prop: %d\n", psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ret = bq24190_charger_set_online(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ret = bq24190_charger_set_temp_alert_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) case POWER_SUPPLY_PROP_CHARGE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) ret = bq24190_charger_set_charge_type(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ret = bq24190_charger_set_current(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ret = bq24190_charger_set_voltage(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) ret = bq24190_charger_set_iinlimit(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int bq24190_charger_property_is_writeable(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) enum power_supply_property psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) case POWER_SUPPLY_PROP_CHARGE_TYPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static void bq24190_input_current_limit_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct bq24190_dev_info *bdi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) container_of(work, struct bq24190_dev_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) input_current_limit_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) power_supply_set_input_current_limit_from_supplier(bdi->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* Sync the input-current-limit with our parent supply (if we have one) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) static void bq24190_charger_external_power_changed(struct power_supply *psy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * The Power-Good detection may take up to 220ms, sometimes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * the external charger detection is quicker, and the bq24190 will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * reset to iinlim based on its own charger detection (which is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * hooked up when using external charger detection) resulting in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * too low default 500mA iinlim. Delay setting the input-current-limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * for 300ms to avoid this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) queue_delayed_work(system_wq, &bdi->input_current_limit_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) msecs_to_jiffies(300));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static enum power_supply_property bq24190_charger_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) POWER_SUPPLY_PROP_CHARGE_TYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) POWER_SUPPLY_PROP_SCOPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) POWER_SUPPLY_PROP_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static char *bq24190_charger_supplied_to[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) "main-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static const struct power_supply_desc bq24190_charger_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) .name = "bq24190-charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .type = POWER_SUPPLY_TYPE_USB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) .properties = bq24190_charger_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) .num_properties = ARRAY_SIZE(bq24190_charger_properties),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) .get_property = bq24190_charger_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) .set_property = bq24190_charger_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) .property_is_writeable = bq24190_charger_property_is_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) .external_power_changed = bq24190_charger_external_power_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) /* Battery power supply property routines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static int bq24190_battery_get_status(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) u8 ss_reg, chrg_fault;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) int status, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) mutex_lock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) chrg_fault = bdi->f_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) mutex_unlock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) chrg_fault &= BQ24190_REG_F_CHRG_FAULT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) chrg_fault >>= BQ24190_REG_F_CHRG_FAULT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) * The battery must be discharging when any of these are true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) * - there is no good power source;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) * - there is a charge fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) * Could also be discharging when in "supplement mode" but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * there is no way to tell when its in that mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (!(ss_reg & BQ24190_REG_SS_PG_STAT_MASK) || chrg_fault) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) status = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ss_reg &= BQ24190_REG_SS_CHRG_STAT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) ss_reg >>= BQ24190_REG_SS_CHRG_STAT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) switch (ss_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) case 0x0: /* Not Charging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) status = POWER_SUPPLY_STATUS_NOT_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) case 0x1: /* Pre-charge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) case 0x2: /* Fast Charging */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) status = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) case 0x3: /* Charge Termination Done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) status = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) val->intval = status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) static int bq24190_battery_get_health(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) int health;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) mutex_lock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) v = bdi->f_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) mutex_unlock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (v & BQ24190_REG_F_BAT_FAULT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) v &= BQ24190_REG_F_NTC_FAULT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) v >>= BQ24190_REG_F_NTC_FAULT_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) switch (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) case 0x0: /* Normal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) health = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) case 0x1: /* TS1 Cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) case 0x3: /* TS2 Cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) case 0x5: /* Both Cold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) health = POWER_SUPPLY_HEALTH_COLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) case 0x2: /* TS1 Hot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) case 0x4: /* TS2 Hot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) case 0x6: /* Both Hot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) health = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) health = POWER_SUPPLY_HEALTH_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) val->intval = health;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int bq24190_battery_get_online(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) u8 batfet_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) ret = bq24190_read_mask(bdi, BQ24190_REG_MOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) BQ24190_REG_MOC_BATFET_DISABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, &batfet_disable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) val->intval = !batfet_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static int bq24190_battery_set_online(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) return bq24190_write_mask(bdi, BQ24190_REG_MOC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) BQ24190_REG_MOC_BATFET_DISABLE_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) BQ24190_REG_MOC_BATFET_DISABLE_SHIFT, !val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static int bq24190_battery_get_temp_alert_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) int temp, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) ret = bq24190_get_field_val(bdi, BQ24190_REG_ICTRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) BQ24190_REG_ICTRC_TREG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) BQ24190_REG_ICTRC_TREG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) bq24190_ictrc_treg_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) ARRAY_SIZE(bq24190_ictrc_treg_values), &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) val->intval = temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) static int bq24190_battery_set_temp_alert_max(struct bq24190_dev_info *bdi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) return bq24190_set_field_val(bdi, BQ24190_REG_ICTRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) BQ24190_REG_ICTRC_TREG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) BQ24190_REG_ICTRC_TREG_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) bq24190_ictrc_treg_values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) ARRAY_SIZE(bq24190_ictrc_treg_values), val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static int bq24190_battery_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) enum power_supply_property psp, union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) dev_dbg(bdi->dev, "prop: %d\n", psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) ret = bq24190_battery_get_status(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) ret = bq24190_battery_get_health(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) ret = bq24190_battery_get_online(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) case POWER_SUPPLY_PROP_TECHNOLOGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* Could be Li-on or Li-polymer but no way to tell which */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) ret = bq24190_battery_get_temp_alert_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) case POWER_SUPPLY_PROP_SCOPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) static int bq24190_battery_set_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) const union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) struct bq24190_dev_info *bdi = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) dev_warn(bdi->dev, "warning: /sys/class/power_supply/bq24190-battery is deprecated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) dev_dbg(bdi->dev, "prop: %d\n", psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) ret = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) ret = bq24190_battery_set_online(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) ret = bq24190_battery_set_temp_alert_max(bdi, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) static int bq24190_battery_property_is_writeable(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) enum power_supply_property psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) case POWER_SUPPLY_PROP_ONLINE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) case POWER_SUPPLY_PROP_TEMP_ALERT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static enum power_supply_property bq24190_battery_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) POWER_SUPPLY_PROP_ONLINE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) POWER_SUPPLY_PROP_TEMP_ALERT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) POWER_SUPPLY_PROP_SCOPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) static const struct power_supply_desc bq24190_battery_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) .name = "bq24190-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) .type = POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) .properties = bq24190_battery_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) .num_properties = ARRAY_SIZE(bq24190_battery_properties),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) .get_property = bq24190_battery_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .set_property = bq24190_battery_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) .property_is_writeable = bq24190_battery_property_is_writeable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) static int bq24190_configure_usb_otg(struct bq24190_dev_info *bdi, u8 ss_reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) bool otg_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) otg_enabled = !!(ss_reg & BQ24190_REG_SS_VBUS_STAT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) ret = extcon_set_state_sync(bdi->edev, EXTCON_USB, otg_enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) dev_err(bdi->dev, "Can't set extcon state to %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) otg_enabled, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) static void bq24190_check_status(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) const u8 battery_mask_ss = BQ24190_REG_SS_CHRG_STAT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) const u8 battery_mask_f = BQ24190_REG_F_BAT_FAULT_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) | BQ24190_REG_F_NTC_FAULT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) bool alert_charger = false, alert_battery = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) u8 ss_reg = 0, f_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) ret = bq24190_read(bdi, BQ24190_REG_SS, &ss_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) dev_err(bdi->dev, "Can't read SS reg: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) ret = bq24190_read(bdi, BQ24190_REG_F, &f_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) dev_err(bdi->dev, "Can't read F reg: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) } while (f_reg && ++i < 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) /* ignore over/under voltage fault after disconnect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) if (f_reg == (1 << BQ24190_REG_F_CHRG_FAULT_SHIFT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) f_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) if (f_reg != bdi->f_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) dev_warn(bdi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) "Fault: boost %d, charge %d, battery %d, ntc %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) !!(f_reg & BQ24190_REG_F_BOOST_FAULT_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) !!(f_reg & BQ24190_REG_F_CHRG_FAULT_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) !!(f_reg & BQ24190_REG_F_BAT_FAULT_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) !!(f_reg & BQ24190_REG_F_NTC_FAULT_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) mutex_lock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) if ((bdi->f_reg & battery_mask_f) != (f_reg & battery_mask_f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) alert_battery = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if ((bdi->f_reg & ~battery_mask_f) != (f_reg & ~battery_mask_f))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) alert_charger = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) bdi->f_reg = f_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) mutex_unlock(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (ss_reg != bdi->ss_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * The device is in host mode so when PG_STAT goes from 1->0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * (i.e., power removed) HIZ needs to be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) if ((bdi->ss_reg & BQ24190_REG_SS_PG_STAT_MASK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) !(ss_reg & BQ24190_REG_SS_PG_STAT_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) ret = bq24190_write_mask(bdi, BQ24190_REG_ISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) BQ24190_REG_ISC_EN_HIZ_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) BQ24190_REG_ISC_EN_HIZ_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) dev_err(bdi->dev, "Can't access ISC reg: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) if ((bdi->ss_reg & battery_mask_ss) != (ss_reg & battery_mask_ss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) alert_battery = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if ((bdi->ss_reg & ~battery_mask_ss) != (ss_reg & ~battery_mask_ss))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) alert_charger = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) bdi->ss_reg = ss_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) if (alert_charger || alert_battery) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) power_supply_changed(bdi->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) bq24190_configure_usb_otg(bdi, ss_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) if (alert_battery && bdi->battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) power_supply_changed(bdi->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) dev_dbg(bdi->dev, "ss_reg: 0x%02x, f_reg: 0x%02x\n", ss_reg, f_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) static irqreturn_t bq24190_irq_handler_thread(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) struct bq24190_dev_info *bdi = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) bdi->irq_event = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) error = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) bq24190_check_status(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) bdi->irq_event = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int bq24190_hw_init(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) u8 v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /* First check that the device really is what its supposed to be */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) ret = bq24190_read_mask(bdi, BQ24190_REG_VPRS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) BQ24190_REG_VPRS_PN_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) BQ24190_REG_VPRS_PN_SHIFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) &v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) switch (v) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) case BQ24190_REG_VPRS_PN_24190:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) case BQ24190_REG_VPRS_PN_24192:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) case BQ24190_REG_VPRS_PN_24192I:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) dev_err(bdi->dev, "Error unknown model: 0x%02x\n", v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) ret = bq24190_register_reset(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) ret = bq24190_set_config(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) return bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) static int bq24190_get_config(struct bq24190_dev_info *bdi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) const char * const s = "ti,system-minimum-microvolt";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) struct power_supply_battery_info info = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) int v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (device_property_read_u32(bdi->dev, s, &v) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) v /= 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) if (v >= BQ24190_REG_POC_SYS_MIN_MIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) && v <= BQ24190_REG_POC_SYS_MIN_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) bdi->sys_min = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) dev_warn(bdi->dev, "invalid value for %s: %u\n", s, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (bdi->dev->of_node &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) !power_supply_get_battery_info(bdi->charger, &info)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) v = info.precharge_current_ua / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) if (v >= BQ24190_REG_PCTCC_IPRECHG_MIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) && v <= BQ24190_REG_PCTCC_IPRECHG_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) bdi->iprechg = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) dev_warn(bdi->dev, "invalid value for battery:precharge-current-microamp: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) v = info.charge_term_current_ua / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (v >= BQ24190_REG_PCTCC_ITERM_MIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) && v <= BQ24190_REG_PCTCC_ITERM_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) bdi->iterm = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) dev_warn(bdi->dev, "invalid value for battery:charge-term-current-microamp: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) static int bq24190_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) struct i2c_adapter *adapter = client->adapter;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) struct power_supply_config charger_cfg = {}, battery_cfg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) struct bq24190_dev_info *bdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) dev_err(dev, "No support for SMBUS_BYTE_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) bdi = devm_kzalloc(dev, sizeof(*bdi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) if (!bdi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) dev_err(dev, "Can't alloc bdi struct\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) bdi->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) bdi->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) strncpy(bdi->model_name, id->name, I2C_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) mutex_init(&bdi->f_reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) bdi->f_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) INIT_DELAYED_WORK(&bdi->input_current_limit_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) bq24190_input_current_limit_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) i2c_set_clientdata(client, bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (client->irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) dev_err(dev, "Can't get irq info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) bdi->edev = devm_extcon_dev_allocate(dev, bq24190_usb_extcon_cable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) if (IS_ERR(bdi->edev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return PTR_ERR(bdi->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) ret = devm_extcon_dev_register(dev, bdi->edev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) pm_runtime_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) pm_runtime_set_autosuspend_delay(dev, 600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) ret = pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) dev_err(dev, "pm_runtime_get failed: %i\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) goto out_pmrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) #ifdef CONFIG_SYSFS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) bq24190_sysfs_init_attrs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) charger_cfg.attr_grp = bq24190_sysfs_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) charger_cfg.drv_data = bdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) charger_cfg.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) charger_cfg.supplied_to = bq24190_charger_supplied_to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) charger_cfg.num_supplicants = ARRAY_SIZE(bq24190_charger_supplied_to),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) bdi->charger = power_supply_register(dev, &bq24190_charger_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) &charger_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) if (IS_ERR(bdi->charger)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) dev_err(dev, "Can't register charger\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) ret = PTR_ERR(bdi->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) goto out_pmrt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) /* the battery class is deprecated and will be removed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) /* in the interim, this property hides it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (!device_property_read_bool(dev, "omit-battery-class")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) battery_cfg.drv_data = bdi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) bdi->battery = power_supply_register(dev, &bq24190_battery_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) &battery_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) if (IS_ERR(bdi->battery)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) dev_err(dev, "Can't register battery\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) ret = PTR_ERR(bdi->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) goto out_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) ret = bq24190_get_config(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) dev_err(dev, "Can't get devicetree config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) goto out_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) ret = bq24190_hw_init(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) dev_err(dev, "Hardware init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) goto out_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) ret = bq24190_configure_usb_otg(bdi, bdi->ss_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) goto out_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) bdi->initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) ret = devm_request_threaded_irq(dev, client->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) bq24190_irq_handler_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) "bq24190-charger", bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) dev_err(dev, "Can't set up irq handler\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) goto out_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) ret = bq24190_register_vbus_regulator(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) goto out_charger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) enable_irq_wake(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) pm_runtime_mark_last_busy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) pm_runtime_put_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) out_charger:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (!IS_ERR_OR_NULL(bdi->battery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) power_supply_unregister(bdi->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) power_supply_unregister(bdi->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) out_pmrt:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) pm_runtime_put_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) pm_runtime_dont_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) static int bq24190_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) error = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) bq24190_register_reset(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) if (bdi->battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) power_supply_unregister(bdi->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) power_supply_unregister(bdi->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (error >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) pm_runtime_put_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) pm_runtime_dont_use_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) pm_runtime_disable(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) static __maybe_unused int bq24190_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) if (!bdi->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) dev_dbg(bdi->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) static __maybe_unused int bq24190_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) if (!bdi->initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) if (!bdi->irq_event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) dev_dbg(bdi->dev, "checking events on possible wakeirq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) bq24190_check_status(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) static __maybe_unused int bq24190_pm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) error = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) bq24190_register_reset(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (error >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) static __maybe_unused int bq24190_pm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) struct bq24190_dev_info *bdi = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) bdi->f_reg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) bdi->ss_reg = BQ24190_REG_SS_VBUS_STAT_MASK; /* impossible state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) error = pm_runtime_get_sync(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) if (error < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) dev_warn(bdi->dev, "pm_runtime_get failed: %i\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) pm_runtime_put_noidle(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) bq24190_register_reset(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) bq24190_set_config(bdi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) bq24190_read(bdi, BQ24190_REG_SS, &bdi->ss_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (error >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) pm_runtime_mark_last_busy(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) pm_runtime_put_autosuspend(bdi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) /* Things may have changed while suspended so alert upper layer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) power_supply_changed(bdi->charger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (bdi->battery)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) power_supply_changed(bdi->battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) static const struct dev_pm_ops bq24190_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) SET_RUNTIME_PM_OPS(bq24190_runtime_suspend, bq24190_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) SET_SYSTEM_SLEEP_PM_OPS(bq24190_pm_suspend, bq24190_pm_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static const struct i2c_device_id bq24190_i2c_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) { "bq24190" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) { "bq24192" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) { "bq24192i" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) { "bq24196" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) MODULE_DEVICE_TABLE(i2c, bq24190_i2c_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) static const struct of_device_id bq24190_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) { .compatible = "ti,bq24190", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) { .compatible = "ti,bq24192", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) { .compatible = "ti,bq24192i", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) { .compatible = "ti,bq24196", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) MODULE_DEVICE_TABLE(of, bq24190_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) static const struct of_device_id bq24190_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) static struct i2c_driver bq24190_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) .probe = bq24190_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) .remove = bq24190_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) .id_table = bq24190_i2c_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) .name = "bq24190-charger",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) .pm = &bq24190_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) .of_match_table = of_match_ptr(bq24190_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) module_i2c_driver(bq24190_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) MODULE_AUTHOR("Mark A. Greer <mgreer@animalcreek.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) MODULE_DESCRIPTION("TI BQ24190 Charger Driver");