^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Gas Gauge driver for SBS Compliant Batteries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2010, NVIDIA Corporation.
^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/bits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/power/sbs-battery.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/power_supply.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) REG_MANUFACTURER_DATA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) REG_BATTERY_MODE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) REG_TEMPERATURE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) REG_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) REG_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) REG_CURRENT_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) REG_MAX_ERR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) REG_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) REG_TIME_TO_EMPTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) REG_TIME_TO_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) REG_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) REG_CAPACITY_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) REG_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) REG_SERIAL_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) REG_REMAINING_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) REG_REMAINING_CAPACITY_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) REG_FULL_CHARGE_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) REG_FULL_CHARGE_CAPACITY_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) REG_DESIGN_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) REG_DESIGN_CAPACITY_CHARGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) REG_DESIGN_VOLTAGE_MIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) REG_DESIGN_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) REG_CHEMISTRY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) REG_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) REG_MODEL_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) REG_CHARGE_CURRENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) REG_CHARGE_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define REG_ADDR_SPEC_INFO 0x1A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define SPEC_INFO_VERSION_MASK GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define SPEC_INFO_VERSION_SHIFT 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define SBS_VERSION_1_0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define SBS_VERSION_1_1 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define SBS_VERSION_1_1_WITH_PEC 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define REG_ADDR_MANUFACTURE_DATE 0x1B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* Battery Mode defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define BATTERY_MODE_OFFSET 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define BATTERY_MODE_CAPACITY_MASK BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) enum sbs_capacity_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) CAPACITY_MODE_AMPS = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) CAPACITY_MODE_WATTS = BATTERY_MODE_CAPACITY_MASK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define BATTERY_MODE_CHARGER_MASK (1<<14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* manufacturer access defines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define MANUFACTURER_ACCESS_STATUS 0x0006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define MANUFACTURER_ACCESS_SLEEP 0x0011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* battery status value bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define BATTERY_INITIALIZED 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define BATTERY_DISCHARGING 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define BATTERY_FULL_CHARGED 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define BATTERY_FULL_DISCHARGED 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* min_value and max_value are only valid for numerical data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define SBS_DATA(_psp, _addr, _min_value, _max_value) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) .psp = _psp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .addr = _addr, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) .min_value = _min_value, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .max_value = _max_value, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static const struct chip_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) enum power_supply_property psp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u8 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) int min_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) int max_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) } sbs_data[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) [REG_MANUFACTURER_DATA] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) SBS_DATA(POWER_SUPPLY_PROP_PRESENT, 0x00, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) [REG_BATTERY_MODE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) SBS_DATA(-1, 0x03, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) [REG_TEMPERATURE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) SBS_DATA(POWER_SUPPLY_PROP_TEMP, 0x08, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) [REG_VOLTAGE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_NOW, 0x09, 0, 20000),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) [REG_CURRENT_NOW] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) SBS_DATA(POWER_SUPPLY_PROP_CURRENT_NOW, 0x0A, -32768, 32767),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) [REG_CURRENT_AVG] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) SBS_DATA(POWER_SUPPLY_PROP_CURRENT_AVG, 0x0B, -32768, 32767),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) [REG_MAX_ERR] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) SBS_DATA(POWER_SUPPLY_PROP_CAPACITY_ERROR_MARGIN, 0x0c, 0, 100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) [REG_CAPACITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) SBS_DATA(POWER_SUPPLY_PROP_CAPACITY, 0x0D, 0, 100),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) [REG_REMAINING_CAPACITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) SBS_DATA(POWER_SUPPLY_PROP_ENERGY_NOW, 0x0F, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) [REG_REMAINING_CAPACITY_CHARGE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) SBS_DATA(POWER_SUPPLY_PROP_CHARGE_NOW, 0x0F, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) [REG_FULL_CHARGE_CAPACITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) SBS_DATA(POWER_SUPPLY_PROP_ENERGY_FULL, 0x10, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) [REG_FULL_CHARGE_CAPACITY_CHARGE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) SBS_DATA(POWER_SUPPLY_PROP_CHARGE_FULL, 0x10, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) [REG_TIME_TO_EMPTY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG, 0x12, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) [REG_TIME_TO_FULL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) SBS_DATA(POWER_SUPPLY_PROP_TIME_TO_FULL_AVG, 0x13, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) [REG_CHARGE_CURRENT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) SBS_DATA(POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX, 0x14, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) [REG_CHARGE_VOLTAGE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) SBS_DATA(POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX, 0x15, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) [REG_STATUS] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) SBS_DATA(POWER_SUPPLY_PROP_STATUS, 0x16, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) [REG_CAPACITY_LEVEL] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) SBS_DATA(POWER_SUPPLY_PROP_CAPACITY_LEVEL, 0x16, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) [REG_CYCLE_COUNT] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) SBS_DATA(POWER_SUPPLY_PROP_CYCLE_COUNT, 0x17, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) [REG_DESIGN_CAPACITY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) SBS_DATA(POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN, 0x18, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) [REG_DESIGN_CAPACITY_CHARGE] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) SBS_DATA(POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, 0x18, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) [REG_DESIGN_VOLTAGE_MIN] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN, 0x19, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) [REG_DESIGN_VOLTAGE_MAX] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) SBS_DATA(POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN, 0x19, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) [REG_SERIAL_NUMBER] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) SBS_DATA(POWER_SUPPLY_PROP_SERIAL_NUMBER, 0x1C, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Properties of type `const char *' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) [REG_MANUFACTURER] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SBS_DATA(POWER_SUPPLY_PROP_MANUFACTURER, 0x20, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) [REG_MODEL_NAME] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) SBS_DATA(POWER_SUPPLY_PROP_MODEL_NAME, 0x21, 0, 65535),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) [REG_CHEMISTRY] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) SBS_DATA(POWER_SUPPLY_PROP_TECHNOLOGY, 0x22, 0, 65535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static const enum power_supply_property sbs_properties[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) POWER_SUPPLY_PROP_STATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) POWER_SUPPLY_PROP_CAPACITY_LEVEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) POWER_SUPPLY_PROP_HEALTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) POWER_SUPPLY_PROP_PRESENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) POWER_SUPPLY_PROP_TECHNOLOGY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) POWER_SUPPLY_PROP_CYCLE_COUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) POWER_SUPPLY_PROP_VOLTAGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) POWER_SUPPLY_PROP_CURRENT_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) POWER_SUPPLY_PROP_CURRENT_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) POWER_SUPPLY_PROP_CAPACITY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) POWER_SUPPLY_PROP_CAPACITY_ERROR_MARGIN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) POWER_SUPPLY_PROP_TEMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) POWER_SUPPLY_PROP_TIME_TO_FULL_AVG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) POWER_SUPPLY_PROP_SERIAL_NUMBER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) POWER_SUPPLY_PROP_ENERGY_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) POWER_SUPPLY_PROP_ENERGY_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) POWER_SUPPLY_PROP_CHARGE_NOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) POWER_SUPPLY_PROP_CHARGE_FULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) POWER_SUPPLY_PROP_MANUFACTURE_YEAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) POWER_SUPPLY_PROP_MANUFACTURE_MONTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) POWER_SUPPLY_PROP_MANUFACTURE_DAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Properties of type `const char *' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) POWER_SUPPLY_PROP_MANUFACTURER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) POWER_SUPPLY_PROP_MODEL_NAME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* Supports special manufacturer commands from TI BQ20Z65 and BQ20Z75 IC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) #define SBS_FLAGS_TI_BQ20ZX5 BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct sbs_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) struct power_supply *power_supply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bool is_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) struct gpio_desc *gpio_detect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) bool charger_broadcasts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int last_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) int poll_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) u32 i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) u32 poll_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) struct delayed_work work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct mutex mode_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) static char model_name[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static char manufacturer[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) static char chemistry[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) static bool force_load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int sbs_read_word_data(struct i2c_client *client, u8 address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int sbs_write_word_data(struct i2c_client *client, u8 address, u16 value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static void sbs_disable_charger_broadcasts(struct sbs_info *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) int val = sbs_read_word_data(chip->client, BATTERY_MODE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) val |= BATTERY_MODE_CHARGER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) val = sbs_write_word_data(chip->client, BATTERY_MODE_OFFSET, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev_err(&chip->client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) "Failed to disable charger broadcasting: %d\n", val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_dbg(&chip->client->dev, "%s\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int sbs_update_presence(struct sbs_info *chip, bool is_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) int retries = chip->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) s32 ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u8 version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (chip->is_present == is_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (!is_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) chip->is_present = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* Disable PEC when no device is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) client->flags &= ~I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) /* Check if device supports packet error checking and use it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) while (retries > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ret = i2c_smbus_read_word_data(client, REG_ADDR_SPEC_INFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * Some batteries trigger the detection pin before the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * I2C bus is properly connected. This works around the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * issue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) retries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) dev_dbg(&client->dev, "failed to read spec info: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /* fallback to old behaviour */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) client->flags &= ~I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) chip->is_present = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) version = (ret & SPEC_INFO_VERSION_MASK) >> SPEC_INFO_VERSION_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (version == SBS_VERSION_1_1_WITH_PEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) client->flags |= I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) client->flags &= ~I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (of_device_is_compatible(client->dev.parent->of_node, "google,cros-ec-i2c-tunnel")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) && client->flags & I2C_CLIENT_PEC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) dev_info(&client->dev, "Disabling PEC because of broken Cros-EC implementation\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) client->flags &= ~I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dev_dbg(&client->dev, "PEC: %s\n", (client->flags & I2C_CLIENT_PEC) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) if (!chip->is_present && is_present && !chip->charger_broadcasts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) sbs_disable_charger_broadcasts(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) chip->is_present = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static int sbs_read_word_data(struct i2c_client *client, u8 address)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int retries = chip->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) s32 ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) while (retries > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = i2c_smbus_read_word_data(client, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) retries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) "%s: i2c read at address 0x%x failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) __func__, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) static int sbs_read_string_data_fallback(struct i2c_client *client, u8 address, char *values)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) s32 ret = 0, block_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) int retries_length, retries_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) retries_length = chip->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) retries_block = chip->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) dev_warn_once(&client->dev, "I2C adapter does not support I2C_FUNC_SMBUS_READ_BLOCK_DATA.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) "Fallback method does not support PEC.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /* Adapter needs to support these two functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!i2c_check_functionality(client->adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) I2C_FUNC_SMBUS_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) I2C_FUNC_SMBUS_I2C_BLOCK)){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* Get the length of block data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) while (retries_length > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ret = i2c_smbus_read_byte_data(client, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) retries_length--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) "%s: i2c read at address 0x%x failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) __func__, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* block_length does not include NULL terminator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) block_length = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (block_length > I2C_SMBUS_BLOCK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) "%s: Returned block_length is longer than 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) __func__, I2C_SMBUS_BLOCK_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* Get the block data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) while (retries_block > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) ret = i2c_smbus_read_i2c_block_data(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) client, address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) block_length + 1, block_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) retries_block--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) "%s: i2c read at address 0x%x failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) __func__, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* block_buffer[0] == block_length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) memcpy(values, block_buffer + 1, block_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) values[block_length] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static int sbs_read_string_data(struct i2c_client *client, u8 address, char *values)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int retries = chip->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_READ_BLOCK_DATA)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) bool pec = client->flags & I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) client->flags &= ~I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) ret = sbs_read_string_data_fallback(client, address, values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (pec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) client->flags |= I2C_CLIENT_PEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) while (retries > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ret = i2c_smbus_read_block_data(client, address, values);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) retries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) dev_dbg(&client->dev, "failed to read block 0x%x: %d\n", address, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) /* add string termination */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) values[ret] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return ret;
^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 int sbs_write_word_data(struct i2c_client *client, u8 address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) u16 value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) int retries = chip->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) s32 ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) while (retries > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = i2c_smbus_write_word_data(client, address, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) retries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) "%s: i2c write to address 0x%x failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) __func__, address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int sbs_status_correct(struct i2c_client *client, int *intval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) ret = sbs_read_word_data(client, sbs_data[REG_CURRENT_NOW].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) ret = (s16)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* Not drawing current -> not charging (i.e. idle) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (*intval != POWER_SUPPLY_STATUS_FULL && ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) *intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) if (*intval == POWER_SUPPLY_STATUS_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) /* Drawing or providing current when full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (ret > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) *intval = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) else if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) *intval = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static bool sbs_bat_needs_calibration(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = sbs_read_word_data(client, sbs_data[REG_BATTERY_MODE].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return !!(ret & BIT(7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) static int sbs_get_ti_battery_presence_and_health(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct i2c_client *client, enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * Write to ManufacturerAccess with ManufacturerAccess command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * and then read the status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = sbs_write_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) MANUFACTURER_ACCESS_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (psp == POWER_SUPPLY_PROP_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) val->intval = 0; /* battery removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = sbs_read_word_data(client, sbs_data[REG_MANUFACTURER_DATA].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (psp == POWER_SUPPLY_PROP_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) val->intval = 0; /* battery removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (ret < sbs_data[REG_MANUFACTURER_DATA].min_value ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) ret > sbs_data[REG_MANUFACTURER_DATA].max_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* Mask the upper nibble of 2nd byte and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * lower byte of response then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * shift the result by 8 to get status*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret &= 0x0F00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret >>= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (psp == POWER_SUPPLY_PROP_PRESENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (ret == 0x0F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) /* battery removed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) val->intval = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) } else if (psp == POWER_SUPPLY_PROP_HEALTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (ret == 0x09)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) else if (ret == 0x0B)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) else if (ret == 0x0C)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) val->intval = POWER_SUPPLY_HEALTH_DEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) else if (sbs_bat_needs_calibration(client))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) val->intval = POWER_SUPPLY_HEALTH_GOOD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int sbs_get_battery_presence_and_health(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct i2c_client *client, enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (chip->flags & SBS_FLAGS_TI_BQ20ZX5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return sbs_get_ti_battery_presence_and_health(client, psp, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Dummy command; if it succeeds, battery is present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) ret = sbs_read_word_data(client, sbs_data[REG_STATUS].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (ret < 0) { /* battery not present*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (psp == POWER_SUPPLY_PROP_PRESENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (psp == POWER_SUPPLY_PROP_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) val->intval = 1; /* battery present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) else { /* POWER_SUPPLY_PROP_HEALTH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (sbs_bat_needs_calibration(client)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) val->intval = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* SBS spec doesn't have a general health command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) val->intval = POWER_SUPPLY_HEALTH_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int sbs_get_battery_property(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) int reg_offset, enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ret = sbs_read_word_data(client, sbs_data[reg_offset].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* returned values are 16 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (sbs_data[reg_offset].min_value < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) ret = (s16)ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (ret >= sbs_data[reg_offset].min_value &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret <= sbs_data[reg_offset].max_value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) val->intval = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (psp == POWER_SUPPLY_PROP_CAPACITY_LEVEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (!(ret & BATTERY_INITIALIZED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) val->intval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) POWER_SUPPLY_CAPACITY_LEVEL_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) else if (ret & BATTERY_FULL_CHARGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) val->intval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) POWER_SUPPLY_CAPACITY_LEVEL_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) else if (ret & BATTERY_FULL_DISCHARGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) val->intval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) val->intval =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) } else if (psp != POWER_SUPPLY_PROP_STATUS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (ret & BATTERY_FULL_CHARGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) val->intval = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else if (ret & BATTERY_DISCHARGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) val->intval = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) sbs_status_correct(client, &val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (chip->poll_time == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) chip->last_state = val->intval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) else if (chip->last_state != val->intval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) cancel_delayed_work_sync(&chip->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) power_supply_changed(chip->power_supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) chip->poll_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (psp == POWER_SUPPLY_PROP_STATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) else if (psp == POWER_SUPPLY_PROP_CAPACITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* sbs spec says that this can be >100 %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * even if max value is 100 %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) val->intval = min(ret, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) val->intval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static int sbs_get_battery_string_property(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int reg_offset, enum power_supply_property psp, char *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) ret = sbs_read_string_data(client, sbs_data[reg_offset].addr, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static void sbs_unit_adjustment(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) enum power_supply_property psp, union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) #define BASE_UNIT_CONVERSION 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) #define BATTERY_MODE_CAP_MULT_WATT (10 * BASE_UNIT_CONVERSION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) #define TIME_UNIT_CONVERSION 60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) #define TEMP_KELVIN_TO_CELSIUS 2731
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) case POWER_SUPPLY_PROP_ENERGY_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case POWER_SUPPLY_PROP_ENERGY_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* sbs provides energy in units of 10mWh.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * Convert to µWh
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) val->intval *= BATTERY_MODE_CAP_MULT_WATT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case POWER_SUPPLY_PROP_CURRENT_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) case POWER_SUPPLY_PROP_CURRENT_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) case POWER_SUPPLY_PROP_CHARGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) case POWER_SUPPLY_PROP_CHARGE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) val->intval *= BASE_UNIT_CONVERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case POWER_SUPPLY_PROP_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* sbs provides battery temperature in 0.1K
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * so convert it to 0.1°C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) val->intval -= TEMP_KELVIN_TO_CELSIUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /* sbs provides time to empty and time to full in minutes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Convert to seconds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) val->intval *= TIME_UNIT_CONVERSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) "%s: no need for unit conversion %d\n", __func__, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static enum sbs_capacity_mode sbs_set_capacity_mode(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) enum sbs_capacity_mode mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) int ret, original_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) original_val = sbs_read_word_data(client, BATTERY_MODE_OFFSET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (original_val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return original_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if ((original_val & BATTERY_MODE_CAPACITY_MASK) == mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (mode == CAPACITY_MODE_AMPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ret = original_val & ~BATTERY_MODE_CAPACITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ret = original_val | BATTERY_MODE_CAPACITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ret = sbs_write_word_data(client, BATTERY_MODE_OFFSET, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return original_val & BATTERY_MODE_CAPACITY_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static int sbs_get_battery_capacity(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) int reg_offset, enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) enum sbs_capacity_mode mode = CAPACITY_MODE_WATTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (power_supply_is_amp_property(psp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) mode = CAPACITY_MODE_AMPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) mode = sbs_set_capacity_mode(client, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if ((int)mode < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) ret = sbs_read_word_data(client, sbs_data[reg_offset].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) val->intval = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) ret = sbs_set_capacity_mode(client, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static char sbs_serial[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static int sbs_get_battery_serial_number(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ret = sbs_read_word_data(client, sbs_data[REG_SERIAL_NUMBER].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) sprintf(sbs_serial, "%04x", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) val->strval = sbs_serial;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int sbs_get_property_index(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) enum power_supply_property psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) for (count = 0; count < ARRAY_SIZE(sbs_data); count++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) if (psp == sbs_data[count].psp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) dev_warn(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) "%s: Invalid Property - %d\n", __func__, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static int sbs_get_chemistry(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) enum power_supply_property psp = POWER_SUPPLY_PROP_TECHNOLOGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ret = sbs_get_property_index(client, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ret = sbs_get_battery_string_property(client, ret, psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) chemistry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (!strncasecmp(chemistry, "LION", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) else if (!strncasecmp(chemistry, "LiP", 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) val->intval = POWER_SUPPLY_TECHNOLOGY_LIPO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) else if (!strncasecmp(chemistry, "NiCd", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) val->intval = POWER_SUPPLY_TECHNOLOGY_NiCd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) else if (!strncasecmp(chemistry, "NiMH", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) val->intval = POWER_SUPPLY_TECHNOLOGY_NiMH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (val->intval == POWER_SUPPLY_TECHNOLOGY_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) dev_warn(&client->dev, "Unknown chemistry: %s\n", chemistry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static int sbs_get_battery_manufacture_date(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) u16 day, month, year;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ret = sbs_read_word_data(client, REG_ADDR_MANUFACTURE_DATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) day = ret & GENMASK(4, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) month = (ret & GENMASK(8, 5)) >> 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) year = ((ret & GENMASK(15, 9)) >> 9) + 1980;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) val->intval = year;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) val->intval = month;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) val->intval = day;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) static int sbs_get_property(struct power_supply *psy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) enum power_supply_property psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) union power_supply_propval *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct sbs_info *chip = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) struct i2c_client *client = chip->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (chip->gpio_detect) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = gpiod_get_value_cansleep(chip->gpio_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (psp == POWER_SUPPLY_PROP_PRESENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) val->intval = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) sbs_update_presence(chip, ret);
^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) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) switch (psp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) case POWER_SUPPLY_PROP_PRESENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) case POWER_SUPPLY_PROP_HEALTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret = sbs_get_battery_presence_and_health(client, psp, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) /* this can only be true if no gpio is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (psp == POWER_SUPPLY_PROP_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) case POWER_SUPPLY_PROP_TECHNOLOGY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ret = sbs_get_chemistry(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) goto done; /* don't trigger power_supply_changed()! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) case POWER_SUPPLY_PROP_ENERGY_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) case POWER_SUPPLY_PROP_ENERGY_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) case POWER_SUPPLY_PROP_CHARGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) case POWER_SUPPLY_PROP_CHARGE_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) ret = sbs_get_property_index(client, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /* sbs_get_battery_capacity() will change the battery mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * temporarily to read the requested attribute. Ensure we stay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * in the desired mode for the duration of the attribute read.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) mutex_lock(&chip->mode_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) ret = sbs_get_battery_capacity(client, ret, psp, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) mutex_unlock(&chip->mode_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) case POWER_SUPPLY_PROP_SERIAL_NUMBER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) ret = sbs_get_battery_serial_number(client, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case POWER_SUPPLY_PROP_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) case POWER_SUPPLY_PROP_CYCLE_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) case POWER_SUPPLY_PROP_VOLTAGE_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) case POWER_SUPPLY_PROP_CURRENT_NOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) case POWER_SUPPLY_PROP_CURRENT_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) case POWER_SUPPLY_PROP_TEMP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) case POWER_SUPPLY_PROP_TIME_TO_FULL_AVG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) case POWER_SUPPLY_PROP_CAPACITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) case POWER_SUPPLY_PROP_CAPACITY_ERROR_MARGIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ret = sbs_get_property_index(client, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ret = sbs_get_battery_property(client, ret, psp, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) case POWER_SUPPLY_PROP_MODEL_NAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ret = sbs_get_property_index(client, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) ret = sbs_get_battery_string_property(client, ret, psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) model_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) val->strval = model_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) case POWER_SUPPLY_PROP_MANUFACTURER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) ret = sbs_get_property_index(client, psp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ret = sbs_get_battery_string_property(client, ret, psp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) manufacturer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) val->strval = manufacturer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ret = sbs_get_battery_manufacture_date(client, psp, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) "%s: INVALID property\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (!chip->gpio_detect && chip->is_present != (ret >= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) bool old_present = chip->is_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) union power_supply_propval val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) int err = sbs_get_battery_presence_and_health(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) client, POWER_SUPPLY_PROP_PRESENT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) sbs_update_presence(chip, !err && val.intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (old_present != chip->is_present)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) power_supply_changed(chip->power_supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) /* Convert units to match requirements for power supply class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) sbs_unit_adjustment(client, psp, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) dev_dbg(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) "%s: property = %d, value = %x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) psp, val->intval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) } else if (!chip->is_present) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) /* battery not present, so return NODATA for properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ret = -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) static void sbs_supply_changed(struct sbs_info *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct power_supply *battery = chip->power_supply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ret = gpiod_get_value_cansleep(chip->gpio_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) sbs_update_presence(chip, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) power_supply_changed(battery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static irqreturn_t sbs_irq(int irq, void *devid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) sbs_supply_changed(devid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) static void sbs_alert(struct i2c_client *client, enum i2c_alert_protocol prot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) unsigned int data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) sbs_supply_changed(i2c_get_clientdata(client));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static void sbs_external_power_changed(struct power_supply *psy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) struct sbs_info *chip = power_supply_get_drvdata(psy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* cancel outstanding work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) cancel_delayed_work_sync(&chip->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) schedule_delayed_work(&chip->work, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) chip->poll_time = chip->poll_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static void sbs_delayed_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct sbs_info *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) s32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) chip = container_of(work, struct sbs_info, work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ret = sbs_read_word_data(chip->client, sbs_data[REG_STATUS].addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /* if the read failed, give up on this work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) chip->poll_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (ret & BATTERY_FULL_CHARGED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ret = POWER_SUPPLY_STATUS_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) else if (ret & BATTERY_DISCHARGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) ret = POWER_SUPPLY_STATUS_DISCHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) ret = POWER_SUPPLY_STATUS_CHARGING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) sbs_status_correct(chip->client, &ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (chip->last_state != ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) chip->poll_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) power_supply_changed(chip->power_supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) if (chip->poll_time > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) schedule_delayed_work(&chip->work, HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) chip->poll_time--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static const struct power_supply_desc sbs_default_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) .type = POWER_SUPPLY_TYPE_BATTERY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) .properties = sbs_properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) .num_properties = ARRAY_SIZE(sbs_properties),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) .get_property = sbs_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) .external_power_changed = sbs_external_power_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static int sbs_probe(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct sbs_info *chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct power_supply_desc *sbs_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct sbs_platform_data *pdata = client->dev.platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct power_supply_config psy_cfg = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) sbs_desc = devm_kmemdup(&client->dev, &sbs_default_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) sizeof(*sbs_desc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!sbs_desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) sbs_desc->name = devm_kasprintf(&client->dev, GFP_KERNEL, "sbs-%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) dev_name(&client->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!sbs_desc->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) chip = devm_kzalloc(&client->dev, sizeof(struct sbs_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (!chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) chip->flags = (u32)(uintptr_t)device_get_match_data(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) chip->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) psy_cfg.of_node = client->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) psy_cfg.drv_data = chip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) chip->last_state = POWER_SUPPLY_STATUS_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) mutex_init(&chip->mode_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) /* use pdata if available, fall back to DT properties,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * or hardcoded defaults if not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) rc = device_property_read_u32(&client->dev, "sbs,i2c-retry-count",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) &chip->i2c_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) chip->i2c_retry_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) rc = device_property_read_u32(&client->dev, "sbs,poll-retry-count",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) &chip->poll_retry_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) chip->poll_retry_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (pdata) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) chip->poll_retry_count = pdata->poll_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) chip->i2c_retry_count = pdata->i2c_retry_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) chip->i2c_retry_count = chip->i2c_retry_count + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) chip->charger_broadcasts = !device_property_read_bool(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) "sbs,disable-charger-broadcasts");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) chip->gpio_detect = devm_gpiod_get_optional(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) "sbs,battery-detect", GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if (IS_ERR(chip->gpio_detect)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) dev_err(&client->dev, "Failed to get gpio: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) PTR_ERR(chip->gpio_detect));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) return PTR_ERR(chip->gpio_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) i2c_set_clientdata(client, chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (!chip->gpio_detect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) goto skip_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) irq = gpiod_to_irq(chip->gpio_detect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) dev_warn(&client->dev, "Failed to get gpio as irq: %d\n", irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) goto skip_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) rc = devm_request_threaded_irq(&client->dev, irq, NULL, sbs_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) dev_name(&client->dev), chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) dev_warn(&client->dev, "Failed to request irq: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) goto skip_gpio;
^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) skip_gpio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * Before we register, we might need to make sure we can actually talk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) * to the battery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) if (!(force_load || chip->gpio_detect)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) union power_supply_propval val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) rc = sbs_get_battery_presence_and_health(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) client, POWER_SUPPLY_PROP_PRESENT, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (rc < 0 || !val.intval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) dev_err(&client->dev, "Failed to get present status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) goto exit_psupply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) INIT_DELAYED_WORK(&chip->work, sbs_delayed_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) chip->power_supply = devm_power_supply_register(&client->dev, sbs_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) &psy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (IS_ERR(chip->power_supply)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) "%s: Failed to register power supply\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) rc = PTR_ERR(chip->power_supply);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) goto exit_psupply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) dev_info(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) "%s: battery gas gauge device registered\n", client->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) exit_psupply:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static int sbs_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) cancel_delayed_work_sync(&chip->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) #if defined CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static int sbs_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) struct i2c_client *client = to_i2c_client(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct sbs_info *chip = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) if (chip->poll_time > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) cancel_delayed_work_sync(&chip->work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (chip->flags & SBS_FLAGS_TI_BQ20ZX5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /* Write to manufacturer access with sleep command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) ret = sbs_write_word_data(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) sbs_data[REG_MANUFACTURER_DATA].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) MANUFACTURER_ACCESS_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (chip->is_present && ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return 0;
^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) static SIMPLE_DEV_PM_OPS(sbs_pm_ops, sbs_suspend, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) #define SBS_PM_OPS (&sbs_pm_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) #define SBS_PM_OPS NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static const struct i2c_device_id sbs_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) { "bq20z65", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) { "bq20z75", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) { "sbs-battery", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) MODULE_DEVICE_TABLE(i2c, sbs_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) static const struct of_device_id sbs_dt_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) { .compatible = "sbs,sbs-battery" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) .compatible = "ti,bq20z65",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) .data = (void *)SBS_FLAGS_TI_BQ20ZX5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .compatible = "ti,bq20z75",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .data = (void *)SBS_FLAGS_TI_BQ20ZX5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) MODULE_DEVICE_TABLE(of, sbs_dt_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static struct i2c_driver sbs_battery_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .probe_new = sbs_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .remove = sbs_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .alert = sbs_alert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .id_table = sbs_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) .name = "sbs-battery",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) .of_match_table = sbs_dt_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) .pm = SBS_PM_OPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) module_i2c_driver(sbs_battery_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) MODULE_DESCRIPTION("SBS battery monitor driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) module_param(force_load, bool, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) MODULE_PARM_DESC(force_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) "Attempt to load the driver even if no battery is connected");