2216 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * BQ27xxx battery driver4 *5 * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>6 * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>7 * Copyright (C) 2010-2011 Lars-Peter Clausen <lars@metafoo.de>8 * Copyright (C) 2011 Pali Rohár <pali@kernel.org>9 * Copyright (C) 2017 Liam Breck <kernel@networkimprov.net>10 *11 * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.12 *13 * Datasheets:14 * https://www.ti.com/product/bq2700015 * https://www.ti.com/product/bq2720016 * https://www.ti.com/product/bq2701017 * https://www.ti.com/product/bq2721018 * https://www.ti.com/product/bq2750019 * https://www.ti.com/product/bq27510-g120 * https://www.ti.com/product/bq27510-g221 * https://www.ti.com/product/bq27510-g322 * https://www.ti.com/product/bq27520-g123 * https://www.ti.com/product/bq27520-g224 * https://www.ti.com/product/bq27520-g325 * https://www.ti.com/product/bq27520-g426 * https://www.ti.com/product/bq27530-g127 * https://www.ti.com/product/bq27531-g128 * https://www.ti.com/product/bq27541-g129 * https://www.ti.com/product/bq27542-g130 * https://www.ti.com/product/bq27546-g131 * https://www.ti.com/product/bq27742-g132 * https://www.ti.com/product/bq27545-g133 * https://www.ti.com/product/bq27421-g134 * https://www.ti.com/product/bq27425-g135 * https://www.ti.com/product/bq2742636 * https://www.ti.com/product/bq27411-g137 * https://www.ti.com/product/bq27441-g138 * https://www.ti.com/product/bq27621-g139 * https://www.ti.com/product/bq27z56140 * https://www.ti.com/product/bq28z61041 * https://www.ti.com/product/bq34z100-g142 * https://www.ti.com/product/bq78z10043 */44 45#include <linux/device.h>46#include <linux/module.h>47#include <linux/mutex.h>48#include <linux/param.h>49#include <linux/jiffies.h>50#include <linux/workqueue.h>51#include <linux/delay.h>52#include <linux/platform_device.h>53#include <linux/power_supply.h>54#include <linux/slab.h>55#include <linux/of.h>56 57#include <linux/power/bq27xxx_battery.h>58 59#define BQ27XXX_MANUFACTURER "Texas Instruments"60 61/* BQ27XXX Flags */62#define BQ27XXX_FLAG_DSC BIT(0)63#define BQ27XXX_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */64#define BQ27XXX_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */65#define BQ27XXX_FLAG_CFGUP BIT(4)66#define BQ27XXX_FLAG_FC BIT(9)67#define BQ27XXX_FLAG_OTD BIT(14)68#define BQ27XXX_FLAG_OTC BIT(15)69#define BQ27XXX_FLAG_UT BIT(14)70#define BQ27XXX_FLAG_OT BIT(15)71 72/* BQ27000 has different layout for Flags register */73#define BQ27000_FLAG_EDVF BIT(0) /* Final End-of-Discharge-Voltage flag */74#define BQ27000_FLAG_EDV1 BIT(1) /* First End-of-Discharge-Voltage flag */75#define BQ27000_FLAG_CI BIT(4) /* Capacity Inaccurate flag */76#define BQ27000_FLAG_FC BIT(5)77#define BQ27000_FLAG_CHGS BIT(7) /* Charge state flag */78 79/* BQ27Z561 has different layout for Flags register */80#define BQ27Z561_FLAG_FDC BIT(4) /* Battery fully discharged */81#define BQ27Z561_FLAG_FC BIT(5) /* Battery fully charged */82#define BQ27Z561_FLAG_DIS_CH BIT(6) /* Battery is discharging */83 84/* control register params */85#define BQ27XXX_SEALED 0x2086#define BQ27XXX_SET_CFGUPDATE 0x1387#define BQ27XXX_SOFT_RESET 0x4288#define BQ27XXX_RESET 0x4189 90#define BQ27XXX_RS (20) /* Resistor sense mOhm */91#define BQ27XXX_POWER_CONSTANT (29200) /* 29.2 µV^2 * 1000 */92#define BQ27XXX_CURRENT_CONSTANT (3570) /* 3.57 µV * 1000 */93 94#define INVALID_REG_ADDR 0xff95 96/*97 * bq27xxx_reg_index - Register names98 *99 * These are indexes into a device's register mapping array.100 */101 102enum bq27xxx_reg_index {103 BQ27XXX_REG_CTRL = 0, /* Control */104 BQ27XXX_REG_TEMP, /* Temperature */105 BQ27XXX_REG_INT_TEMP, /* Internal Temperature */106 BQ27XXX_REG_VOLT, /* Voltage */107 BQ27XXX_REG_AI, /* Average Current */108 BQ27XXX_REG_FLAGS, /* Flags */109 BQ27XXX_REG_TTE, /* Time-to-Empty */110 BQ27XXX_REG_TTF, /* Time-to-Full */111 BQ27XXX_REG_TTES, /* Time-to-Empty Standby */112 BQ27XXX_REG_TTECP, /* Time-to-Empty at Constant Power */113 BQ27XXX_REG_NAC, /* Nominal Available Capacity */114 BQ27XXX_REG_RC, /* Remaining Capacity */115 BQ27XXX_REG_FCC, /* Full Charge Capacity */116 BQ27XXX_REG_CYCT, /* Cycle Count */117 BQ27XXX_REG_AE, /* Available Energy */118 BQ27XXX_REG_SOC, /* State-of-Charge */119 BQ27XXX_REG_DCAP, /* Design Capacity */120 BQ27XXX_REG_AP, /* Average Power */121 BQ27XXX_DM_CTRL, /* Block Data Control */122 BQ27XXX_DM_CLASS, /* Data Class */123 BQ27XXX_DM_BLOCK, /* Data Block */124 BQ27XXX_DM_DATA, /* Block Data */125 BQ27XXX_DM_CKSUM, /* Block Data Checksum */126 BQ27XXX_REG_MAX, /* sentinel */127};128 129#define BQ27XXX_DM_REG_ROWS \130 [BQ27XXX_DM_CTRL] = 0x61, \131 [BQ27XXX_DM_CLASS] = 0x3e, \132 [BQ27XXX_DM_BLOCK] = 0x3f, \133 [BQ27XXX_DM_DATA] = 0x40, \134 [BQ27XXX_DM_CKSUM] = 0x60135 136/* Register mappings */137static u8138 bq27000_regs[BQ27XXX_REG_MAX] = {139 [BQ27XXX_REG_CTRL] = 0x00,140 [BQ27XXX_REG_TEMP] = 0x06,141 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,142 [BQ27XXX_REG_VOLT] = 0x08,143 [BQ27XXX_REG_AI] = 0x14,144 [BQ27XXX_REG_FLAGS] = 0x0a,145 [BQ27XXX_REG_TTE] = 0x16,146 [BQ27XXX_REG_TTF] = 0x18,147 [BQ27XXX_REG_TTES] = 0x1c,148 [BQ27XXX_REG_TTECP] = 0x26,149 [BQ27XXX_REG_NAC] = 0x0c,150 [BQ27XXX_REG_RC] = INVALID_REG_ADDR,151 [BQ27XXX_REG_FCC] = 0x12,152 [BQ27XXX_REG_CYCT] = 0x2a,153 [BQ27XXX_REG_AE] = 0x22,154 [BQ27XXX_REG_SOC] = 0x0b,155 [BQ27XXX_REG_DCAP] = 0x76,156 [BQ27XXX_REG_AP] = 0x24,157 [BQ27XXX_DM_CTRL] = INVALID_REG_ADDR,158 [BQ27XXX_DM_CLASS] = INVALID_REG_ADDR,159 [BQ27XXX_DM_BLOCK] = INVALID_REG_ADDR,160 [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,161 [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,162 },163 bq27010_regs[BQ27XXX_REG_MAX] = {164 [BQ27XXX_REG_CTRL] = 0x00,165 [BQ27XXX_REG_TEMP] = 0x06,166 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,167 [BQ27XXX_REG_VOLT] = 0x08,168 [BQ27XXX_REG_AI] = 0x14,169 [BQ27XXX_REG_FLAGS] = 0x0a,170 [BQ27XXX_REG_TTE] = 0x16,171 [BQ27XXX_REG_TTF] = 0x18,172 [BQ27XXX_REG_TTES] = 0x1c,173 [BQ27XXX_REG_TTECP] = 0x26,174 [BQ27XXX_REG_NAC] = 0x0c,175 [BQ27XXX_REG_RC] = INVALID_REG_ADDR,176 [BQ27XXX_REG_FCC] = 0x12,177 [BQ27XXX_REG_CYCT] = 0x2a,178 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,179 [BQ27XXX_REG_SOC] = 0x0b,180 [BQ27XXX_REG_DCAP] = 0x76,181 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,182 [BQ27XXX_DM_CTRL] = INVALID_REG_ADDR,183 [BQ27XXX_DM_CLASS] = INVALID_REG_ADDR,184 [BQ27XXX_DM_BLOCK] = INVALID_REG_ADDR,185 [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,186 [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,187 },188 bq2750x_regs[BQ27XXX_REG_MAX] = {189 [BQ27XXX_REG_CTRL] = 0x00,190 [BQ27XXX_REG_TEMP] = 0x06,191 [BQ27XXX_REG_INT_TEMP] = 0x28,192 [BQ27XXX_REG_VOLT] = 0x08,193 [BQ27XXX_REG_AI] = 0x14,194 [BQ27XXX_REG_FLAGS] = 0x0a,195 [BQ27XXX_REG_TTE] = 0x16,196 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,197 [BQ27XXX_REG_TTES] = 0x1a,198 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,199 [BQ27XXX_REG_NAC] = 0x0c,200 [BQ27XXX_REG_RC] = 0x10,201 [BQ27XXX_REG_FCC] = 0x12,202 [BQ27XXX_REG_CYCT] = 0x2a,203 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,204 [BQ27XXX_REG_SOC] = 0x2c,205 [BQ27XXX_REG_DCAP] = 0x3c,206 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,207 BQ27XXX_DM_REG_ROWS,208 },209#define bq2751x_regs bq27510g3_regs210#define bq2752x_regs bq27510g3_regs211 bq27500_regs[BQ27XXX_REG_MAX] = {212 [BQ27XXX_REG_CTRL] = 0x00,213 [BQ27XXX_REG_TEMP] = 0x06,214 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,215 [BQ27XXX_REG_VOLT] = 0x08,216 [BQ27XXX_REG_AI] = 0x14,217 [BQ27XXX_REG_FLAGS] = 0x0a,218 [BQ27XXX_REG_TTE] = 0x16,219 [BQ27XXX_REG_TTF] = 0x18,220 [BQ27XXX_REG_TTES] = 0x1c,221 [BQ27XXX_REG_TTECP] = 0x26,222 [BQ27XXX_REG_NAC] = 0x0c,223 [BQ27XXX_REG_RC] = 0x10,224 [BQ27XXX_REG_FCC] = 0x12,225 [BQ27XXX_REG_CYCT] = 0x2a,226 [BQ27XXX_REG_AE] = 0x22,227 [BQ27XXX_REG_SOC] = 0x2c,228 [BQ27XXX_REG_DCAP] = 0x3c,229 [BQ27XXX_REG_AP] = 0x24,230 BQ27XXX_DM_REG_ROWS,231 },232#define bq27510g1_regs bq27500_regs233#define bq27510g2_regs bq27500_regs234 bq27510g3_regs[BQ27XXX_REG_MAX] = {235 [BQ27XXX_REG_CTRL] = 0x00,236 [BQ27XXX_REG_TEMP] = 0x06,237 [BQ27XXX_REG_INT_TEMP] = 0x28,238 [BQ27XXX_REG_VOLT] = 0x08,239 [BQ27XXX_REG_AI] = 0x14,240 [BQ27XXX_REG_FLAGS] = 0x0a,241 [BQ27XXX_REG_TTE] = 0x16,242 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,243 [BQ27XXX_REG_TTES] = 0x1a,244 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,245 [BQ27XXX_REG_NAC] = 0x0c,246 [BQ27XXX_REG_RC] = 0x10,247 [BQ27XXX_REG_FCC] = 0x12,248 [BQ27XXX_REG_CYCT] = 0x1e,249 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,250 [BQ27XXX_REG_SOC] = 0x20,251 [BQ27XXX_REG_DCAP] = 0x2e,252 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,253 BQ27XXX_DM_REG_ROWS,254 },255 bq27520g1_regs[BQ27XXX_REG_MAX] = {256 [BQ27XXX_REG_CTRL] = 0x00,257 [BQ27XXX_REG_TEMP] = 0x06,258 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,259 [BQ27XXX_REG_VOLT] = 0x08,260 [BQ27XXX_REG_AI] = 0x14,261 [BQ27XXX_REG_FLAGS] = 0x0a,262 [BQ27XXX_REG_TTE] = 0x16,263 [BQ27XXX_REG_TTF] = 0x18,264 [BQ27XXX_REG_TTES] = 0x1c,265 [BQ27XXX_REG_TTECP] = 0x26,266 [BQ27XXX_REG_NAC] = 0x0c,267 [BQ27XXX_REG_RC] = 0x10,268 [BQ27XXX_REG_FCC] = 0x12,269 [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,270 [BQ27XXX_REG_AE] = 0x22,271 [BQ27XXX_REG_SOC] = 0x2c,272 [BQ27XXX_REG_DCAP] = 0x3c,273 [BQ27XXX_REG_AP] = 0x24,274 BQ27XXX_DM_REG_ROWS,275 },276 bq27520g2_regs[BQ27XXX_REG_MAX] = {277 [BQ27XXX_REG_CTRL] = 0x00,278 [BQ27XXX_REG_TEMP] = 0x06,279 [BQ27XXX_REG_INT_TEMP] = 0x36,280 [BQ27XXX_REG_VOLT] = 0x08,281 [BQ27XXX_REG_AI] = 0x14,282 [BQ27XXX_REG_FLAGS] = 0x0a,283 [BQ27XXX_REG_TTE] = 0x16,284 [BQ27XXX_REG_TTF] = 0x18,285 [BQ27XXX_REG_TTES] = 0x1c,286 [BQ27XXX_REG_TTECP] = 0x26,287 [BQ27XXX_REG_NAC] = 0x0c,288 [BQ27XXX_REG_RC] = 0x10,289 [BQ27XXX_REG_FCC] = 0x12,290 [BQ27XXX_REG_CYCT] = 0x2a,291 [BQ27XXX_REG_AE] = 0x22,292 [BQ27XXX_REG_SOC] = 0x2c,293 [BQ27XXX_REG_DCAP] = 0x3c,294 [BQ27XXX_REG_AP] = 0x24,295 BQ27XXX_DM_REG_ROWS,296 },297 bq27520g3_regs[BQ27XXX_REG_MAX] = {298 [BQ27XXX_REG_CTRL] = 0x00,299 [BQ27XXX_REG_TEMP] = 0x06,300 [BQ27XXX_REG_INT_TEMP] = 0x36,301 [BQ27XXX_REG_VOLT] = 0x08,302 [BQ27XXX_REG_AI] = 0x14,303 [BQ27XXX_REG_FLAGS] = 0x0a,304 [BQ27XXX_REG_TTE] = 0x16,305 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,306 [BQ27XXX_REG_TTES] = 0x1c,307 [BQ27XXX_REG_TTECP] = 0x26,308 [BQ27XXX_REG_NAC] = 0x0c,309 [BQ27XXX_REG_RC] = 0x10,310 [BQ27XXX_REG_FCC] = 0x12,311 [BQ27XXX_REG_CYCT] = 0x2a,312 [BQ27XXX_REG_AE] = 0x22,313 [BQ27XXX_REG_SOC] = 0x2c,314 [BQ27XXX_REG_DCAP] = 0x3c,315 [BQ27XXX_REG_AP] = 0x24,316 BQ27XXX_DM_REG_ROWS,317 },318 bq27520g4_regs[BQ27XXX_REG_MAX] = {319 [BQ27XXX_REG_CTRL] = 0x00,320 [BQ27XXX_REG_TEMP] = 0x06,321 [BQ27XXX_REG_INT_TEMP] = 0x28,322 [BQ27XXX_REG_VOLT] = 0x08,323 [BQ27XXX_REG_AI] = 0x14,324 [BQ27XXX_REG_FLAGS] = 0x0a,325 [BQ27XXX_REG_TTE] = 0x16,326 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,327 [BQ27XXX_REG_TTES] = 0x1c,328 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,329 [BQ27XXX_REG_NAC] = 0x0c,330 [BQ27XXX_REG_RC] = 0x10,331 [BQ27XXX_REG_FCC] = 0x12,332 [BQ27XXX_REG_CYCT] = 0x1e,333 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,334 [BQ27XXX_REG_SOC] = 0x20,335 [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,336 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,337 BQ27XXX_DM_REG_ROWS,338 },339 bq27521_regs[BQ27XXX_REG_MAX] = {340 [BQ27XXX_REG_CTRL] = 0x02,341 [BQ27XXX_REG_TEMP] = 0x0a,342 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,343 [BQ27XXX_REG_VOLT] = 0x0c,344 [BQ27XXX_REG_AI] = 0x0e,345 [BQ27XXX_REG_FLAGS] = 0x08,346 [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,347 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,348 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,349 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,350 [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,351 [BQ27XXX_REG_RC] = INVALID_REG_ADDR,352 [BQ27XXX_REG_FCC] = INVALID_REG_ADDR,353 [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,354 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,355 [BQ27XXX_REG_SOC] = INVALID_REG_ADDR,356 [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,357 [BQ27XXX_REG_AP] = INVALID_REG_ADDR,358 [BQ27XXX_DM_CTRL] = INVALID_REG_ADDR,359 [BQ27XXX_DM_CLASS] = INVALID_REG_ADDR,360 [BQ27XXX_DM_BLOCK] = INVALID_REG_ADDR,361 [BQ27XXX_DM_DATA] = INVALID_REG_ADDR,362 [BQ27XXX_DM_CKSUM] = INVALID_REG_ADDR,363 },364 bq27530_regs[BQ27XXX_REG_MAX] = {365 [BQ27XXX_REG_CTRL] = 0x00,366 [BQ27XXX_REG_TEMP] = 0x06,367 [BQ27XXX_REG_INT_TEMP] = 0x32,368 [BQ27XXX_REG_VOLT] = 0x08,369 [BQ27XXX_REG_AI] = 0x14,370 [BQ27XXX_REG_FLAGS] = 0x0a,371 [BQ27XXX_REG_TTE] = 0x16,372 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,373 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,374 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,375 [BQ27XXX_REG_NAC] = 0x0c,376 [BQ27XXX_REG_RC] = 0x10,377 [BQ27XXX_REG_FCC] = 0x12,378 [BQ27XXX_REG_CYCT] = 0x2a,379 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,380 [BQ27XXX_REG_SOC] = 0x2c,381 [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,382 [BQ27XXX_REG_AP] = 0x24,383 BQ27XXX_DM_REG_ROWS,384 },385#define bq27531_regs bq27530_regs386 bq27541_regs[BQ27XXX_REG_MAX] = {387 [BQ27XXX_REG_CTRL] = 0x00,388 [BQ27XXX_REG_TEMP] = 0x06,389 [BQ27XXX_REG_INT_TEMP] = 0x28,390 [BQ27XXX_REG_VOLT] = 0x08,391 [BQ27XXX_REG_AI] = 0x14,392 [BQ27XXX_REG_FLAGS] = 0x0a,393 [BQ27XXX_REG_TTE] = 0x16,394 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,395 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,396 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,397 [BQ27XXX_REG_NAC] = 0x0c,398 [BQ27XXX_REG_RC] = 0x10,399 [BQ27XXX_REG_FCC] = 0x12,400 [BQ27XXX_REG_CYCT] = 0x2a,401 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,402 [BQ27XXX_REG_SOC] = 0x2c,403 [BQ27XXX_REG_DCAP] = 0x3c,404 [BQ27XXX_REG_AP] = 0x24,405 BQ27XXX_DM_REG_ROWS,406 },407#define bq27542_regs bq27541_regs408#define bq27546_regs bq27541_regs409#define bq27742_regs bq27541_regs410 bq27545_regs[BQ27XXX_REG_MAX] = {411 [BQ27XXX_REG_CTRL] = 0x00,412 [BQ27XXX_REG_TEMP] = 0x06,413 [BQ27XXX_REG_INT_TEMP] = 0x28,414 [BQ27XXX_REG_VOLT] = 0x08,415 [BQ27XXX_REG_AI] = 0x14,416 [BQ27XXX_REG_FLAGS] = 0x0a,417 [BQ27XXX_REG_TTE] = 0x16,418 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,419 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,420 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,421 [BQ27XXX_REG_NAC] = 0x0c,422 [BQ27XXX_REG_RC] = 0x10,423 [BQ27XXX_REG_FCC] = 0x12,424 [BQ27XXX_REG_CYCT] = 0x2a,425 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,426 [BQ27XXX_REG_SOC] = 0x2c,427 [BQ27XXX_REG_DCAP] = INVALID_REG_ADDR,428 [BQ27XXX_REG_AP] = 0x24,429 BQ27XXX_DM_REG_ROWS,430 },431 bq27421_regs[BQ27XXX_REG_MAX] = {432 [BQ27XXX_REG_CTRL] = 0x00,433 [BQ27XXX_REG_TEMP] = 0x02,434 [BQ27XXX_REG_INT_TEMP] = 0x1e,435 [BQ27XXX_REG_VOLT] = 0x04,436 [BQ27XXX_REG_AI] = 0x10,437 [BQ27XXX_REG_FLAGS] = 0x06,438 [BQ27XXX_REG_TTE] = INVALID_REG_ADDR,439 [BQ27XXX_REG_TTF] = INVALID_REG_ADDR,440 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,441 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,442 [BQ27XXX_REG_NAC] = 0x08,443 [BQ27XXX_REG_RC] = 0x0c,444 [BQ27XXX_REG_FCC] = 0x0e,445 [BQ27XXX_REG_CYCT] = INVALID_REG_ADDR,446 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,447 [BQ27XXX_REG_SOC] = 0x1c,448 [BQ27XXX_REG_DCAP] = 0x3c,449 [BQ27XXX_REG_AP] = 0x18,450 BQ27XXX_DM_REG_ROWS,451 },452#define bq27411_regs bq27421_regs453#define bq27425_regs bq27421_regs454#define bq27426_regs bq27421_regs455#define bq27441_regs bq27421_regs456#define bq27621_regs bq27421_regs457 bq27z561_regs[BQ27XXX_REG_MAX] = {458 [BQ27XXX_REG_CTRL] = 0x00,459 [BQ27XXX_REG_TEMP] = 0x06,460 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,461 [BQ27XXX_REG_VOLT] = 0x08,462 [BQ27XXX_REG_AI] = 0x14,463 [BQ27XXX_REG_FLAGS] = 0x0a,464 [BQ27XXX_REG_TTE] = 0x16,465 [BQ27XXX_REG_TTF] = 0x18,466 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,467 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,468 [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,469 [BQ27XXX_REG_RC] = 0x10,470 [BQ27XXX_REG_FCC] = 0x12,471 [BQ27XXX_REG_CYCT] = 0x2a,472 [BQ27XXX_REG_AE] = 0x22,473 [BQ27XXX_REG_SOC] = 0x2c,474 [BQ27XXX_REG_DCAP] = 0x3c,475 [BQ27XXX_REG_AP] = 0x22,476 BQ27XXX_DM_REG_ROWS,477 },478 bq28z610_regs[BQ27XXX_REG_MAX] = {479 [BQ27XXX_REG_CTRL] = 0x00,480 [BQ27XXX_REG_TEMP] = 0x06,481 [BQ27XXX_REG_INT_TEMP] = INVALID_REG_ADDR,482 [BQ27XXX_REG_VOLT] = 0x08,483 [BQ27XXX_REG_AI] = 0x14,484 [BQ27XXX_REG_FLAGS] = 0x0a,485 [BQ27XXX_REG_TTE] = 0x16,486 [BQ27XXX_REG_TTF] = 0x18,487 [BQ27XXX_REG_TTES] = INVALID_REG_ADDR,488 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,489 [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,490 [BQ27XXX_REG_RC] = 0x10,491 [BQ27XXX_REG_FCC] = 0x12,492 [BQ27XXX_REG_CYCT] = 0x2a,493 [BQ27XXX_REG_AE] = 0x22,494 [BQ27XXX_REG_SOC] = 0x2c,495 [BQ27XXX_REG_DCAP] = 0x3c,496 [BQ27XXX_REG_AP] = 0x22,497 BQ27XXX_DM_REG_ROWS,498 },499 bq34z100_regs[BQ27XXX_REG_MAX] = {500 [BQ27XXX_REG_CTRL] = 0x00,501 [BQ27XXX_REG_TEMP] = 0x0c,502 [BQ27XXX_REG_INT_TEMP] = 0x2a,503 [BQ27XXX_REG_VOLT] = 0x08,504 [BQ27XXX_REG_AI] = 0x0a,505 [BQ27XXX_REG_FLAGS] = 0x0e,506 [BQ27XXX_REG_TTE] = 0x18,507 [BQ27XXX_REG_TTF] = 0x1a,508 [BQ27XXX_REG_TTES] = 0x1e,509 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,510 [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,511 [BQ27XXX_REG_RC] = 0x04,512 [BQ27XXX_REG_FCC] = 0x06,513 [BQ27XXX_REG_CYCT] = 0x2c,514 [BQ27XXX_REG_AE] = 0x24,515 [BQ27XXX_REG_SOC] = 0x02,516 [BQ27XXX_REG_DCAP] = 0x3c,517 [BQ27XXX_REG_AP] = 0x22,518 BQ27XXX_DM_REG_ROWS,519 },520 bq78z100_regs[BQ27XXX_REG_MAX] = {521 [BQ27XXX_REG_CTRL] = 0x00,522 [BQ27XXX_REG_TEMP] = 0x06,523 [BQ27XXX_REG_INT_TEMP] = 0x28,524 [BQ27XXX_REG_VOLT] = 0x08,525 [BQ27XXX_REG_AI] = 0x14,526 [BQ27XXX_REG_FLAGS] = 0x0a,527 [BQ27XXX_REG_TTE] = 0x16,528 [BQ27XXX_REG_TTF] = 0x18,529 [BQ27XXX_REG_TTES] = 0x1c,530 [BQ27XXX_REG_TTECP] = INVALID_REG_ADDR,531 [BQ27XXX_REG_NAC] = INVALID_REG_ADDR,532 [BQ27XXX_REG_RC] = 0x10,533 [BQ27XXX_REG_FCC] = 0x12,534 [BQ27XXX_REG_CYCT] = 0x2a,535 [BQ27XXX_REG_AE] = INVALID_REG_ADDR,536 [BQ27XXX_REG_SOC] = 0x2c,537 [BQ27XXX_REG_DCAP] = 0x3c,538 [BQ27XXX_REG_AP] = 0x22,539 BQ27XXX_DM_REG_ROWS,540 };541 542static enum power_supply_property bq27000_props[] = {543 POWER_SUPPLY_PROP_STATUS,544 POWER_SUPPLY_PROP_PRESENT,545 POWER_SUPPLY_PROP_VOLTAGE_NOW,546 POWER_SUPPLY_PROP_CURRENT_NOW,547 POWER_SUPPLY_PROP_CAPACITY,548 POWER_SUPPLY_PROP_CAPACITY_LEVEL,549 POWER_SUPPLY_PROP_TEMP,550 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,551 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,552 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,553 POWER_SUPPLY_PROP_TECHNOLOGY,554 POWER_SUPPLY_PROP_CHARGE_FULL,555 POWER_SUPPLY_PROP_CHARGE_NOW,556 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,557 POWER_SUPPLY_PROP_CYCLE_COUNT,558 POWER_SUPPLY_PROP_ENERGY_NOW,559 POWER_SUPPLY_PROP_POWER_AVG,560 POWER_SUPPLY_PROP_HEALTH,561 POWER_SUPPLY_PROP_MANUFACTURER,562};563 564static enum power_supply_property bq27010_props[] = {565 POWER_SUPPLY_PROP_STATUS,566 POWER_SUPPLY_PROP_PRESENT,567 POWER_SUPPLY_PROP_VOLTAGE_NOW,568 POWER_SUPPLY_PROP_CURRENT_NOW,569 POWER_SUPPLY_PROP_CAPACITY,570 POWER_SUPPLY_PROP_CAPACITY_LEVEL,571 POWER_SUPPLY_PROP_TEMP,572 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,573 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,574 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,575 POWER_SUPPLY_PROP_TECHNOLOGY,576 POWER_SUPPLY_PROP_CHARGE_FULL,577 POWER_SUPPLY_PROP_CHARGE_NOW,578 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,579 POWER_SUPPLY_PROP_CYCLE_COUNT,580 POWER_SUPPLY_PROP_HEALTH,581 POWER_SUPPLY_PROP_MANUFACTURER,582};583 584#define bq2750x_props bq27510g3_props585#define bq2751x_props bq27510g3_props586#define bq2752x_props bq27510g3_props587 588static enum power_supply_property bq27500_props[] = {589 POWER_SUPPLY_PROP_STATUS,590 POWER_SUPPLY_PROP_PRESENT,591 POWER_SUPPLY_PROP_VOLTAGE_NOW,592 POWER_SUPPLY_PROP_CURRENT_NOW,593 POWER_SUPPLY_PROP_CAPACITY,594 POWER_SUPPLY_PROP_CAPACITY_LEVEL,595 POWER_SUPPLY_PROP_TEMP,596 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,597 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,598 POWER_SUPPLY_PROP_TECHNOLOGY,599 POWER_SUPPLY_PROP_CHARGE_FULL,600 POWER_SUPPLY_PROP_CHARGE_NOW,601 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,602 POWER_SUPPLY_PROP_CYCLE_COUNT,603 POWER_SUPPLY_PROP_ENERGY_NOW,604 POWER_SUPPLY_PROP_POWER_AVG,605 POWER_SUPPLY_PROP_HEALTH,606 POWER_SUPPLY_PROP_MANUFACTURER,607};608#define bq27510g1_props bq27500_props609#define bq27510g2_props bq27500_props610 611static enum power_supply_property bq27510g3_props[] = {612 POWER_SUPPLY_PROP_STATUS,613 POWER_SUPPLY_PROP_PRESENT,614 POWER_SUPPLY_PROP_VOLTAGE_NOW,615 POWER_SUPPLY_PROP_CURRENT_NOW,616 POWER_SUPPLY_PROP_CAPACITY,617 POWER_SUPPLY_PROP_CAPACITY_LEVEL,618 POWER_SUPPLY_PROP_TEMP,619 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,620 POWER_SUPPLY_PROP_TECHNOLOGY,621 POWER_SUPPLY_PROP_CHARGE_FULL,622 POWER_SUPPLY_PROP_CHARGE_NOW,623 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,624 POWER_SUPPLY_PROP_CYCLE_COUNT,625 POWER_SUPPLY_PROP_HEALTH,626 POWER_SUPPLY_PROP_MANUFACTURER,627};628 629static enum power_supply_property bq27520g1_props[] = {630 POWER_SUPPLY_PROP_STATUS,631 POWER_SUPPLY_PROP_PRESENT,632 POWER_SUPPLY_PROP_VOLTAGE_NOW,633 POWER_SUPPLY_PROP_CURRENT_NOW,634 POWER_SUPPLY_PROP_CAPACITY,635 POWER_SUPPLY_PROP_CAPACITY_LEVEL,636 POWER_SUPPLY_PROP_TEMP,637 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,638 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,639 POWER_SUPPLY_PROP_TECHNOLOGY,640 POWER_SUPPLY_PROP_CHARGE_FULL,641 POWER_SUPPLY_PROP_CHARGE_NOW,642 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,643 POWER_SUPPLY_PROP_ENERGY_NOW,644 POWER_SUPPLY_PROP_POWER_AVG,645 POWER_SUPPLY_PROP_HEALTH,646 POWER_SUPPLY_PROP_MANUFACTURER,647};648 649#define bq27520g2_props bq27500_props650 651static enum power_supply_property bq27520g3_props[] = {652 POWER_SUPPLY_PROP_STATUS,653 POWER_SUPPLY_PROP_PRESENT,654 POWER_SUPPLY_PROP_VOLTAGE_NOW,655 POWER_SUPPLY_PROP_CURRENT_NOW,656 POWER_SUPPLY_PROP_CAPACITY,657 POWER_SUPPLY_PROP_CAPACITY_LEVEL,658 POWER_SUPPLY_PROP_TEMP,659 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,660 POWER_SUPPLY_PROP_TECHNOLOGY,661 POWER_SUPPLY_PROP_CHARGE_FULL,662 POWER_SUPPLY_PROP_CHARGE_NOW,663 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,664 POWER_SUPPLY_PROP_CYCLE_COUNT,665 POWER_SUPPLY_PROP_ENERGY_NOW,666 POWER_SUPPLY_PROP_POWER_AVG,667 POWER_SUPPLY_PROP_HEALTH,668 POWER_SUPPLY_PROP_MANUFACTURER,669};670 671static enum power_supply_property bq27520g4_props[] = {672 POWER_SUPPLY_PROP_STATUS,673 POWER_SUPPLY_PROP_PRESENT,674 POWER_SUPPLY_PROP_VOLTAGE_NOW,675 POWER_SUPPLY_PROP_CURRENT_NOW,676 POWER_SUPPLY_PROP_CAPACITY,677 POWER_SUPPLY_PROP_CAPACITY_LEVEL,678 POWER_SUPPLY_PROP_TEMP,679 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,680 POWER_SUPPLY_PROP_TECHNOLOGY,681 POWER_SUPPLY_PROP_CHARGE_FULL,682 POWER_SUPPLY_PROP_CHARGE_NOW,683 POWER_SUPPLY_PROP_CYCLE_COUNT,684 POWER_SUPPLY_PROP_HEALTH,685 POWER_SUPPLY_PROP_MANUFACTURER,686};687 688static enum power_supply_property bq27521_props[] = {689 POWER_SUPPLY_PROP_STATUS,690 POWER_SUPPLY_PROP_PRESENT,691 POWER_SUPPLY_PROP_VOLTAGE_NOW,692 POWER_SUPPLY_PROP_CURRENT_NOW,693 POWER_SUPPLY_PROP_TEMP,694 POWER_SUPPLY_PROP_TECHNOLOGY,695};696 697static enum power_supply_property bq27530_props[] = {698 POWER_SUPPLY_PROP_STATUS,699 POWER_SUPPLY_PROP_PRESENT,700 POWER_SUPPLY_PROP_VOLTAGE_NOW,701 POWER_SUPPLY_PROP_CURRENT_NOW,702 POWER_SUPPLY_PROP_CAPACITY,703 POWER_SUPPLY_PROP_CAPACITY_LEVEL,704 POWER_SUPPLY_PROP_TEMP,705 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,706 POWER_SUPPLY_PROP_TECHNOLOGY,707 POWER_SUPPLY_PROP_CHARGE_FULL,708 POWER_SUPPLY_PROP_CHARGE_NOW,709 POWER_SUPPLY_PROP_POWER_AVG,710 POWER_SUPPLY_PROP_HEALTH,711 POWER_SUPPLY_PROP_CYCLE_COUNT,712 POWER_SUPPLY_PROP_MANUFACTURER,713};714#define bq27531_props bq27530_props715 716static enum power_supply_property bq27541_props[] = {717 POWER_SUPPLY_PROP_STATUS,718 POWER_SUPPLY_PROP_PRESENT,719 POWER_SUPPLY_PROP_VOLTAGE_NOW,720 POWER_SUPPLY_PROP_CURRENT_NOW,721 POWER_SUPPLY_PROP_CAPACITY,722 POWER_SUPPLY_PROP_CAPACITY_LEVEL,723 POWER_SUPPLY_PROP_TEMP,724 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,725 POWER_SUPPLY_PROP_TECHNOLOGY,726 POWER_SUPPLY_PROP_CHARGE_FULL,727 POWER_SUPPLY_PROP_CHARGE_NOW,728 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,729 POWER_SUPPLY_PROP_CYCLE_COUNT,730 POWER_SUPPLY_PROP_POWER_AVG,731 POWER_SUPPLY_PROP_HEALTH,732 POWER_SUPPLY_PROP_MANUFACTURER,733};734#define bq27542_props bq27541_props735#define bq27546_props bq27541_props736#define bq27742_props bq27541_props737 738static enum power_supply_property bq27545_props[] = {739 POWER_SUPPLY_PROP_STATUS,740 POWER_SUPPLY_PROP_PRESENT,741 POWER_SUPPLY_PROP_VOLTAGE_NOW,742 POWER_SUPPLY_PROP_CURRENT_NOW,743 POWER_SUPPLY_PROP_CAPACITY,744 POWER_SUPPLY_PROP_CAPACITY_LEVEL,745 POWER_SUPPLY_PROP_TEMP,746 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,747 POWER_SUPPLY_PROP_TECHNOLOGY,748 POWER_SUPPLY_PROP_CHARGE_FULL,749 POWER_SUPPLY_PROP_CHARGE_NOW,750 POWER_SUPPLY_PROP_HEALTH,751 POWER_SUPPLY_PROP_CYCLE_COUNT,752 POWER_SUPPLY_PROP_POWER_AVG,753 POWER_SUPPLY_PROP_MANUFACTURER,754};755 756static enum power_supply_property bq27421_props[] = {757 POWER_SUPPLY_PROP_STATUS,758 POWER_SUPPLY_PROP_PRESENT,759 POWER_SUPPLY_PROP_VOLTAGE_NOW,760 POWER_SUPPLY_PROP_CURRENT_NOW,761 POWER_SUPPLY_PROP_CAPACITY,762 POWER_SUPPLY_PROP_CAPACITY_LEVEL,763 POWER_SUPPLY_PROP_TEMP,764 POWER_SUPPLY_PROP_TECHNOLOGY,765 POWER_SUPPLY_PROP_CHARGE_FULL,766 POWER_SUPPLY_PROP_CHARGE_NOW,767 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,768 POWER_SUPPLY_PROP_MANUFACTURER,769};770#define bq27411_props bq27421_props771#define bq27425_props bq27421_props772#define bq27426_props bq27421_props773#define bq27441_props bq27421_props774#define bq27621_props bq27421_props775 776static enum power_supply_property bq27z561_props[] = {777 POWER_SUPPLY_PROP_STATUS,778 POWER_SUPPLY_PROP_PRESENT,779 POWER_SUPPLY_PROP_VOLTAGE_NOW,780 POWER_SUPPLY_PROP_CURRENT_NOW,781 POWER_SUPPLY_PROP_CAPACITY,782 POWER_SUPPLY_PROP_CAPACITY_LEVEL,783 POWER_SUPPLY_PROP_TEMP,784 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,785 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,786 POWER_SUPPLY_PROP_TECHNOLOGY,787 POWER_SUPPLY_PROP_CHARGE_FULL,788 POWER_SUPPLY_PROP_CHARGE_NOW,789 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,790 POWER_SUPPLY_PROP_CYCLE_COUNT,791 POWER_SUPPLY_PROP_POWER_AVG,792 POWER_SUPPLY_PROP_HEALTH,793 POWER_SUPPLY_PROP_MANUFACTURER,794};795 796static enum power_supply_property bq28z610_props[] = {797 POWER_SUPPLY_PROP_STATUS,798 POWER_SUPPLY_PROP_PRESENT,799 POWER_SUPPLY_PROP_VOLTAGE_NOW,800 POWER_SUPPLY_PROP_CURRENT_NOW,801 POWER_SUPPLY_PROP_CAPACITY,802 POWER_SUPPLY_PROP_CAPACITY_LEVEL,803 POWER_SUPPLY_PROP_TEMP,804 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,805 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,806 POWER_SUPPLY_PROP_TECHNOLOGY,807 POWER_SUPPLY_PROP_CHARGE_FULL,808 POWER_SUPPLY_PROP_CHARGE_NOW,809 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,810 POWER_SUPPLY_PROP_CYCLE_COUNT,811 POWER_SUPPLY_PROP_POWER_AVG,812 POWER_SUPPLY_PROP_HEALTH,813 POWER_SUPPLY_PROP_MANUFACTURER,814};815 816static enum power_supply_property bq34z100_props[] = {817 POWER_SUPPLY_PROP_STATUS,818 POWER_SUPPLY_PROP_PRESENT,819 POWER_SUPPLY_PROP_VOLTAGE_NOW,820 POWER_SUPPLY_PROP_CURRENT_NOW,821 POWER_SUPPLY_PROP_CAPACITY,822 POWER_SUPPLY_PROP_CAPACITY_LEVEL,823 POWER_SUPPLY_PROP_TEMP,824 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,825 POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,826 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,827 POWER_SUPPLY_PROP_TECHNOLOGY,828 POWER_SUPPLY_PROP_CHARGE_FULL,829 POWER_SUPPLY_PROP_CHARGE_NOW,830 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,831 POWER_SUPPLY_PROP_CYCLE_COUNT,832 POWER_SUPPLY_PROP_ENERGY_NOW,833 POWER_SUPPLY_PROP_POWER_AVG,834 POWER_SUPPLY_PROP_HEALTH,835 POWER_SUPPLY_PROP_MANUFACTURER,836};837 838static enum power_supply_property bq78z100_props[] = {839 POWER_SUPPLY_PROP_STATUS,840 POWER_SUPPLY_PROP_PRESENT,841 POWER_SUPPLY_PROP_VOLTAGE_NOW,842 POWER_SUPPLY_PROP_CURRENT_NOW,843 POWER_SUPPLY_PROP_CAPACITY,844 POWER_SUPPLY_PROP_CAPACITY_LEVEL,845 POWER_SUPPLY_PROP_TEMP,846 POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,847 POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,848 POWER_SUPPLY_PROP_TECHNOLOGY,849 POWER_SUPPLY_PROP_CHARGE_FULL,850 POWER_SUPPLY_PROP_CHARGE_NOW,851 POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,852 POWER_SUPPLY_PROP_CYCLE_COUNT,853 POWER_SUPPLY_PROP_POWER_AVG,854 POWER_SUPPLY_PROP_HEALTH,855 POWER_SUPPLY_PROP_MANUFACTURER,856};857 858struct bq27xxx_dm_reg {859 u8 subclass_id;860 u8 offset;861 u8 bytes;862 u16 min, max;863};864 865enum bq27xxx_dm_reg_id {866 BQ27XXX_DM_DESIGN_CAPACITY = 0,867 BQ27XXX_DM_DESIGN_ENERGY,868 BQ27XXX_DM_TERMINATE_VOLTAGE,869};870 871#define bq27000_dm_regs NULL872#define bq27010_dm_regs NULL873#define bq2750x_dm_regs NULL874#define bq2751x_dm_regs NULL875#define bq2752x_dm_regs NULL876 877#if 0 /* not yet tested */878static struct bq27xxx_dm_reg bq27500_dm_regs[] = {879 [BQ27XXX_DM_DESIGN_CAPACITY] = { 48, 10, 2, 0, 65535 },880 [BQ27XXX_DM_DESIGN_ENERGY] = { }, /* missing on chip */881 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 80, 48, 2, 1000, 32767 },882};883#else884#define bq27500_dm_regs NULL885#endif886 887/* todo create data memory definitions from datasheets and test on chips */888#define bq27510g1_dm_regs NULL889#define bq27510g2_dm_regs NULL890#define bq27510g3_dm_regs NULL891#define bq27520g1_dm_regs NULL892#define bq27520g2_dm_regs NULL893#define bq27520g3_dm_regs NULL894#define bq27520g4_dm_regs NULL895#define bq27521_dm_regs NULL896#define bq27530_dm_regs NULL897#define bq27531_dm_regs NULL898#define bq27541_dm_regs NULL899#define bq27542_dm_regs NULL900#define bq27546_dm_regs NULL901#define bq27742_dm_regs NULL902 903#if 0 /* not yet tested */904static struct bq27xxx_dm_reg bq27545_dm_regs[] = {905 [BQ27XXX_DM_DESIGN_CAPACITY] = { 48, 23, 2, 0, 32767 },906 [BQ27XXX_DM_DESIGN_ENERGY] = { 48, 25, 2, 0, 32767 },907 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 80, 67, 2, 2800, 3700 },908};909#else910#define bq27545_dm_regs NULL911#endif912 913static struct bq27xxx_dm_reg bq27411_dm_regs[] = {914 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 32767 },915 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },916 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 16, 2, 2800, 3700 },917};918 919static struct bq27xxx_dm_reg bq27421_dm_regs[] = {920 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 10, 2, 0, 8000 },921 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 12, 2, 0, 32767 },922 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 16, 2, 2500, 3700 },923};924 925static struct bq27xxx_dm_reg bq27425_dm_regs[] = {926 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 12, 2, 0, 32767 },927 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 14, 2, 0, 32767 },928 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 18, 2, 2800, 3700 },929};930 931static struct bq27xxx_dm_reg bq27426_dm_regs[] = {932 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 6, 2, 0, 8000 },933 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 8, 2, 0, 32767 },934 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 10, 2, 2500, 3700 },935};936 937#if 0 /* not yet tested */938#define bq27441_dm_regs bq27421_dm_regs939#else940#define bq27441_dm_regs NULL941#endif942 943#if 0 /* not yet tested */944static struct bq27xxx_dm_reg bq27621_dm_regs[] = {945 [BQ27XXX_DM_DESIGN_CAPACITY] = { 82, 3, 2, 0, 8000 },946 [BQ27XXX_DM_DESIGN_ENERGY] = { 82, 5, 2, 0, 32767 },947 [BQ27XXX_DM_TERMINATE_VOLTAGE] = { 82, 9, 2, 2500, 3700 },948};949#else950#define bq27621_dm_regs NULL951#endif952 953#define bq27z561_dm_regs NULL954#define bq28z610_dm_regs NULL955#define bq34z100_dm_regs NULL956#define bq78z100_dm_regs NULL957 958#define BQ27XXX_O_ZERO BIT(0)959#define BQ27XXX_O_OTDC BIT(1) /* has OTC/OTD overtemperature flags */960#define BQ27XXX_O_UTOT BIT(2) /* has OT overtemperature flag */961#define BQ27XXX_O_CFGUP BIT(3)962#define BQ27XXX_O_RAM BIT(4)963#define BQ27Z561_O_BITS BIT(5)964#define BQ27XXX_O_SOC_SI BIT(6) /* SoC is single register */965#define BQ27XXX_O_HAS_CI BIT(7) /* has Capacity Inaccurate flag */966#define BQ27XXX_O_MUL_CHEM BIT(8) /* multiple chemistries supported */967 968#define BQ27XXX_DATA(ref, key, opt) { \969 .opts = (opt), \970 .unseal_key = key, \971 .regs = ref##_regs, \972 .dm_regs = ref##_dm_regs, \973 .props = ref##_props, \974 .props_size = ARRAY_SIZE(ref##_props) }975 976static struct {977 u32 opts;978 u32 unseal_key;979 u8 *regs;980 struct bq27xxx_dm_reg *dm_regs;981 enum power_supply_property *props;982 size_t props_size;983} bq27xxx_chip_data[] = {984 [BQ27000] = BQ27XXX_DATA(bq27000, 0 , BQ27XXX_O_ZERO | BQ27XXX_O_SOC_SI | BQ27XXX_O_HAS_CI),985 [BQ27010] = BQ27XXX_DATA(bq27010, 0 , BQ27XXX_O_ZERO | BQ27XXX_O_SOC_SI | BQ27XXX_O_HAS_CI),986 [BQ2750X] = BQ27XXX_DATA(bq2750x, 0 , BQ27XXX_O_OTDC),987 [BQ2751X] = BQ27XXX_DATA(bq2751x, 0 , BQ27XXX_O_OTDC),988 [BQ2752X] = BQ27XXX_DATA(bq2752x, 0 , BQ27XXX_O_OTDC),989 [BQ27500] = BQ27XXX_DATA(bq27500, 0x04143672, BQ27XXX_O_OTDC),990 [BQ27510G1] = BQ27XXX_DATA(bq27510g1, 0 , BQ27XXX_O_OTDC),991 [BQ27510G2] = BQ27XXX_DATA(bq27510g2, 0 , BQ27XXX_O_OTDC),992 [BQ27510G3] = BQ27XXX_DATA(bq27510g3, 0 , BQ27XXX_O_OTDC),993 [BQ27520G1] = BQ27XXX_DATA(bq27520g1, 0 , BQ27XXX_O_OTDC),994 [BQ27520G2] = BQ27XXX_DATA(bq27520g2, 0 , BQ27XXX_O_OTDC),995 [BQ27520G3] = BQ27XXX_DATA(bq27520g3, 0 , BQ27XXX_O_OTDC),996 [BQ27520G4] = BQ27XXX_DATA(bq27520g4, 0 , BQ27XXX_O_OTDC),997 [BQ27521] = BQ27XXX_DATA(bq27521, 0 , 0),998 [BQ27530] = BQ27XXX_DATA(bq27530, 0 , BQ27XXX_O_UTOT),999 [BQ27531] = BQ27XXX_DATA(bq27531, 0 , BQ27XXX_O_UTOT),1000 [BQ27541] = BQ27XXX_DATA(bq27541, 0 , BQ27XXX_O_OTDC),1001 [BQ27542] = BQ27XXX_DATA(bq27542, 0 , BQ27XXX_O_OTDC),1002 [BQ27546] = BQ27XXX_DATA(bq27546, 0 , BQ27XXX_O_OTDC),1003 [BQ27742] = BQ27XXX_DATA(bq27742, 0 , BQ27XXX_O_OTDC),1004 [BQ27545] = BQ27XXX_DATA(bq27545, 0x04143672, BQ27XXX_O_OTDC),1005 [BQ27411] = BQ27XXX_DATA(bq27411, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),1006 [BQ27421] = BQ27XXX_DATA(bq27421, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),1007 [BQ27425] = BQ27XXX_DATA(bq27425, 0x04143672, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP),1008 [BQ27426] = BQ27XXX_DATA(bq27426, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),1009 [BQ27441] = BQ27XXX_DATA(bq27441, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),1010 [BQ27621] = BQ27XXX_DATA(bq27621, 0x80008000, BQ27XXX_O_UTOT | BQ27XXX_O_CFGUP | BQ27XXX_O_RAM),1011 [BQ27Z561] = BQ27XXX_DATA(bq27z561, 0 , BQ27Z561_O_BITS),1012 [BQ28Z610] = BQ27XXX_DATA(bq28z610, 0 , BQ27Z561_O_BITS),1013 [BQ34Z100] = BQ27XXX_DATA(bq34z100, 0 , BQ27XXX_O_OTDC | BQ27XXX_O_SOC_SI | \1014 BQ27XXX_O_HAS_CI | BQ27XXX_O_MUL_CHEM),1015 [BQ78Z100] = BQ27XXX_DATA(bq78z100, 0 , BQ27Z561_O_BITS),1016};1017 1018static DEFINE_MUTEX(bq27xxx_list_lock);1019static LIST_HEAD(bq27xxx_battery_devices);1020 1021#define BQ27XXX_MSLEEP(i) usleep_range((i)*1000, (i)*1000+500)1022 1023#define BQ27XXX_DM_SZ 321024 1025/**1026 * struct bq27xxx_dm_buf - chip data memory buffer1027 * @class: data memory subclass_id1028 * @block: data memory block number1029 * @data: data from/for the block1030 * @has_data: true if data has been filled by read1031 * @dirty: true if data has changed since last read/write1032 *1033 * Encapsulates info required to manage chip data memory blocks.1034 */1035struct bq27xxx_dm_buf {1036 u8 class;1037 u8 block;1038 u8 data[BQ27XXX_DM_SZ];1039 bool has_data, dirty;1040};1041 1042#define BQ27XXX_DM_BUF(di, i) { \1043 .class = (di)->dm_regs[i].subclass_id, \1044 .block = (di)->dm_regs[i].offset / BQ27XXX_DM_SZ, \1045}1046 1047static inline __be16 *bq27xxx_dm_reg_ptr(struct bq27xxx_dm_buf *buf,1048 struct bq27xxx_dm_reg *reg)1049{1050 if (buf->class == reg->subclass_id &&1051 buf->block == reg->offset / BQ27XXX_DM_SZ)1052 return (__be16 *) (buf->data + reg->offset % BQ27XXX_DM_SZ);1053 1054 return NULL;1055}1056 1057static const char * const bq27xxx_dm_reg_name[] = {1058 [BQ27XXX_DM_DESIGN_CAPACITY] = "design-capacity",1059 [BQ27XXX_DM_DESIGN_ENERGY] = "design-energy",1060 [BQ27XXX_DM_TERMINATE_VOLTAGE] = "terminate-voltage",1061};1062 1063 1064static bool bq27xxx_dt_to_nvm = true;1065module_param_named(dt_monitored_battery_updates_nvm, bq27xxx_dt_to_nvm, bool, 0444);1066MODULE_PARM_DESC(dt_monitored_battery_updates_nvm,1067 "Devicetree monitored-battery config updates data memory on NVM/flash chips.\n"1068 "Users must set this =0 when installing a different type of battery!\n"1069 "Default is =1."1070#ifndef CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM1071 "\nSetting this affects future kernel updates, not the current configuration."1072#endif1073);1074 1075static int poll_interval_param_set(const char *val, const struct kernel_param *kp)1076{1077 struct bq27xxx_device_info *di;1078 unsigned int prev_val = *(unsigned int *) kp->arg;1079 int ret;1080 1081 ret = param_set_uint(val, kp);1082 if (ret < 0 || prev_val == *(unsigned int *) kp->arg)1083 return ret;1084 1085 mutex_lock(&bq27xxx_list_lock);1086 list_for_each_entry(di, &bq27xxx_battery_devices, list)1087 mod_delayed_work(system_wq, &di->work, 0);1088 mutex_unlock(&bq27xxx_list_lock);1089 1090 return ret;1091}1092 1093static const struct kernel_param_ops param_ops_poll_interval = {1094 .get = param_get_uint,1095 .set = poll_interval_param_set,1096};1097 1098static unsigned int poll_interval = 360;1099module_param_cb(poll_interval, ¶m_ops_poll_interval, &poll_interval, 0644);1100MODULE_PARM_DESC(poll_interval,1101 "battery poll interval in seconds - 0 disables polling");1102 1103/*1104 * Common code for BQ27xxx devices1105 */1106 1107static inline int bq27xxx_read(struct bq27xxx_device_info *di, int reg_index,1108 bool single)1109{1110 int ret;1111 1112 if (!di || di->regs[reg_index] == INVALID_REG_ADDR)1113 return -EINVAL;1114 1115 ret = di->bus.read(di, di->regs[reg_index], single);1116 if (ret < 0)1117 dev_dbg(di->dev, "failed to read register 0x%02x (index %d)\n",1118 di->regs[reg_index], reg_index);1119 1120 return ret;1121}1122 1123static inline int bq27xxx_write(struct bq27xxx_device_info *di, int reg_index,1124 u16 value, bool single)1125{1126 int ret;1127 1128 if (!di || di->regs[reg_index] == INVALID_REG_ADDR)1129 return -EINVAL;1130 1131 if (!di->bus.write)1132 return -EPERM;1133 1134 ret = di->bus.write(di, di->regs[reg_index], value, single);1135 if (ret < 0)1136 dev_dbg(di->dev, "failed to write register 0x%02x (index %d)\n",1137 di->regs[reg_index], reg_index);1138 1139 return ret;1140}1141 1142static inline int bq27xxx_read_block(struct bq27xxx_device_info *di, int reg_index,1143 u8 *data, int len)1144{1145 int ret;1146 1147 if (!di || di->regs[reg_index] == INVALID_REG_ADDR)1148 return -EINVAL;1149 1150 if (!di->bus.read_bulk)1151 return -EPERM;1152 1153 ret = di->bus.read_bulk(di, di->regs[reg_index], data, len);1154 if (ret < 0)1155 dev_dbg(di->dev, "failed to read_bulk register 0x%02x (index %d)\n",1156 di->regs[reg_index], reg_index);1157 1158 return ret;1159}1160 1161static inline int bq27xxx_write_block(struct bq27xxx_device_info *di, int reg_index,1162 u8 *data, int len)1163{1164 int ret;1165 1166 if (!di || di->regs[reg_index] == INVALID_REG_ADDR)1167 return -EINVAL;1168 1169 if (!di->bus.write_bulk)1170 return -EPERM;1171 1172 ret = di->bus.write_bulk(di, di->regs[reg_index], data, len);1173 if (ret < 0)1174 dev_dbg(di->dev, "failed to write_bulk register 0x%02x (index %d)\n",1175 di->regs[reg_index], reg_index);1176 1177 return ret;1178}1179 1180static int bq27xxx_battery_seal(struct bq27xxx_device_info *di)1181{1182 int ret;1183 1184 ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, BQ27XXX_SEALED, false);1185 if (ret < 0) {1186 dev_err(di->dev, "bus error on seal: %d\n", ret);1187 return ret;1188 }1189 1190 return 0;1191}1192 1193static int bq27xxx_battery_unseal(struct bq27xxx_device_info *di)1194{1195 int ret;1196 1197 if (di->unseal_key == 0) {1198 dev_err(di->dev, "unseal failed due to missing key\n");1199 return -EINVAL;1200 }1201 1202 ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, (u16)(di->unseal_key >> 16), false);1203 if (ret < 0)1204 goto out;1205 1206 ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, (u16)di->unseal_key, false);1207 if (ret < 0)1208 goto out;1209 1210 return 0;1211 1212out:1213 dev_err(di->dev, "bus error on unseal: %d\n", ret);1214 return ret;1215}1216 1217static u8 bq27xxx_battery_checksum_dm_block(struct bq27xxx_dm_buf *buf)1218{1219 u16 sum = 0;1220 int i;1221 1222 for (i = 0; i < BQ27XXX_DM_SZ; i++)1223 sum += buf->data[i];1224 sum &= 0xff;1225 1226 return 0xff - sum;1227}1228 1229static int bq27xxx_battery_read_dm_block(struct bq27xxx_device_info *di,1230 struct bq27xxx_dm_buf *buf)1231{1232 int ret;1233 1234 buf->has_data = false;1235 1236 ret = bq27xxx_write(di, BQ27XXX_DM_CLASS, buf->class, true);1237 if (ret < 0)1238 goto out;1239 1240 ret = bq27xxx_write(di, BQ27XXX_DM_BLOCK, buf->block, true);1241 if (ret < 0)1242 goto out;1243 1244 BQ27XXX_MSLEEP(1);1245 1246 ret = bq27xxx_read_block(di, BQ27XXX_DM_DATA, buf->data, BQ27XXX_DM_SZ);1247 if (ret < 0)1248 goto out;1249 1250 ret = bq27xxx_read(di, BQ27XXX_DM_CKSUM, true);1251 if (ret < 0)1252 goto out;1253 1254 if ((u8)ret != bq27xxx_battery_checksum_dm_block(buf)) {1255 ret = -EINVAL;1256 goto out;1257 }1258 1259 buf->has_data = true;1260 buf->dirty = false;1261 1262 return 0;1263 1264out:1265 dev_err(di->dev, "bus error reading chip memory: %d\n", ret);1266 return ret;1267}1268 1269static void bq27xxx_battery_update_dm_block(struct bq27xxx_device_info *di,1270 struct bq27xxx_dm_buf *buf,1271 enum bq27xxx_dm_reg_id reg_id,1272 unsigned int val)1273{1274 struct bq27xxx_dm_reg *reg = &di->dm_regs[reg_id];1275 const char *str = bq27xxx_dm_reg_name[reg_id];1276 __be16 *prev = bq27xxx_dm_reg_ptr(buf, reg);1277 1278 if (prev == NULL) {1279 dev_warn(di->dev, "buffer does not match %s dm spec\n", str);1280 return;1281 }1282 1283 if (reg->bytes != 2) {1284 dev_warn(di->dev, "%s dm spec has unsupported byte size\n", str);1285 return;1286 }1287 1288 if (!buf->has_data)1289 return;1290 1291 if (be16_to_cpup(prev) == val) {1292 dev_info(di->dev, "%s has %u\n", str, val);1293 return;1294 }1295 1296#ifdef CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM1297 if (!(di->opts & BQ27XXX_O_RAM) && !bq27xxx_dt_to_nvm) {1298#else1299 if (!(di->opts & BQ27XXX_O_RAM)) {1300#endif1301 /* devicetree and NVM differ; defer to NVM */1302 dev_warn(di->dev, "%s has %u; update to %u disallowed "1303#ifdef CONFIG_BATTERY_BQ27XXX_DT_UPDATES_NVM1304 "by dt_monitored_battery_updates_nvm=0"1305#else1306 "for flash/NVM data memory"1307#endif1308 "\n", str, be16_to_cpup(prev), val);1309 return;1310 }1311 1312 dev_info(di->dev, "update %s to %u\n", str, val);1313 1314 *prev = cpu_to_be16(val);1315 buf->dirty = true;1316}1317 1318static int bq27xxx_battery_cfgupdate_priv(struct bq27xxx_device_info *di, bool active)1319{1320 const int limit = 100;1321 u16 cmd = active ? BQ27XXX_SET_CFGUPDATE : BQ27XXX_SOFT_RESET;1322 int ret, try = limit;1323 1324 ret = bq27xxx_write(di, BQ27XXX_REG_CTRL, cmd, false);1325 if (ret < 0)1326 return ret;1327 1328 do {1329 BQ27XXX_MSLEEP(25);1330 ret = bq27xxx_read(di, BQ27XXX_REG_FLAGS, false);1331 if (ret < 0)1332 return ret;1333 } while (!!(ret & BQ27XXX_FLAG_CFGUP) != active && --try);1334 1335 if (!try && di->chip != BQ27425) { // 425 has a bug1336 dev_err(di->dev, "timed out waiting for cfgupdate flag %d\n", active);1337 return -EINVAL;1338 }1339 1340 if (limit - try > 3)1341 dev_warn(di->dev, "cfgupdate %d, retries %d\n", active, limit - try);1342 1343 return 0;1344}1345 1346static inline int bq27xxx_battery_set_cfgupdate(struct bq27xxx_device_info *di)1347{1348 int ret = bq27xxx_battery_cfgupdate_priv(di, true);1349 if (ret < 0 && ret != -EINVAL)1350 dev_err(di->dev, "bus error on set_cfgupdate: %d\n", ret);1351 1352 return ret;1353}1354 1355static inline int bq27xxx_battery_soft_reset(struct bq27xxx_device_info *di)1356{1357 int ret = bq27xxx_battery_cfgupdate_priv(di, false);1358 if (ret < 0 && ret != -EINVAL)1359 dev_err(di->dev, "bus error on soft_reset: %d\n", ret);1360 1361 return ret;1362}1363 1364static int bq27xxx_battery_write_dm_block(struct bq27xxx_device_info *di,1365 struct bq27xxx_dm_buf *buf)1366{1367 bool cfgup = di->opts & BQ27XXX_O_CFGUP;1368 int ret;1369 1370 if (!buf->dirty)1371 return 0;1372 1373 if (cfgup) {1374 ret = bq27xxx_battery_set_cfgupdate(di);1375 if (ret < 0)1376 return ret;1377 }1378 1379 ret = bq27xxx_write(di, BQ27XXX_DM_CTRL, 0, true);1380 if (ret < 0)1381 goto out;1382 1383 ret = bq27xxx_write(di, BQ27XXX_DM_CLASS, buf->class, true);1384 if (ret < 0)1385 goto out;1386 1387 ret = bq27xxx_write(di, BQ27XXX_DM_BLOCK, buf->block, true);1388 if (ret < 0)1389 goto out;1390 1391 BQ27XXX_MSLEEP(1);1392 1393 ret = bq27xxx_write_block(di, BQ27XXX_DM_DATA, buf->data, BQ27XXX_DM_SZ);1394 if (ret < 0)1395 goto out;1396 1397 ret = bq27xxx_write(di, BQ27XXX_DM_CKSUM,1398 bq27xxx_battery_checksum_dm_block(buf), true);1399 if (ret < 0)1400 goto out;1401 1402 /* DO NOT read BQ27XXX_DM_CKSUM here to verify it! That may cause NVM1403 * corruption on the '425 chip (and perhaps others), which can damage1404 * the chip.1405 */1406 1407 if (cfgup) {1408 BQ27XXX_MSLEEP(1);1409 ret = bq27xxx_battery_soft_reset(di);1410 if (ret < 0)1411 return ret;1412 } else {1413 BQ27XXX_MSLEEP(100); /* flash DM updates in <100ms */1414 }1415 1416 buf->dirty = false;1417 1418 return 0;1419 1420out:1421 if (cfgup)1422 bq27xxx_battery_soft_reset(di);1423 1424 dev_err(di->dev, "bus error writing chip memory: %d\n", ret);1425 return ret;1426}1427 1428static void bq27xxx_battery_set_config(struct bq27xxx_device_info *di,1429 struct power_supply_battery_info *info)1430{1431 struct bq27xxx_dm_buf bd = BQ27XXX_DM_BUF(di, BQ27XXX_DM_DESIGN_CAPACITY);1432 struct bq27xxx_dm_buf bt = BQ27XXX_DM_BUF(di, BQ27XXX_DM_TERMINATE_VOLTAGE);1433 bool updated;1434 1435 if (bq27xxx_battery_unseal(di) < 0)1436 return;1437 1438 if (info->charge_full_design_uah != -EINVAL &&1439 info->energy_full_design_uwh != -EINVAL) {1440 bq27xxx_battery_read_dm_block(di, &bd);1441 /* assume design energy & capacity are in same block */1442 bq27xxx_battery_update_dm_block(di, &bd,1443 BQ27XXX_DM_DESIGN_CAPACITY,1444 info->charge_full_design_uah / 1000);1445 bq27xxx_battery_update_dm_block(di, &bd,1446 BQ27XXX_DM_DESIGN_ENERGY,1447 info->energy_full_design_uwh / 1000);1448 }1449 1450 if (info->voltage_min_design_uv != -EINVAL) {1451 bool same = bd.class == bt.class && bd.block == bt.block;1452 if (!same)1453 bq27xxx_battery_read_dm_block(di, &bt);1454 bq27xxx_battery_update_dm_block(di, same ? &bd : &bt,1455 BQ27XXX_DM_TERMINATE_VOLTAGE,1456 info->voltage_min_design_uv / 1000);1457 }1458 1459 updated = bd.dirty || bt.dirty;1460 1461 bq27xxx_battery_write_dm_block(di, &bd);1462 bq27xxx_battery_write_dm_block(di, &bt);1463 1464 bq27xxx_battery_seal(di);1465 1466 if (updated && !(di->opts & BQ27XXX_O_CFGUP)) {1467 bq27xxx_write(di, BQ27XXX_REG_CTRL, BQ27XXX_RESET, false);1468 BQ27XXX_MSLEEP(300); /* reset time is not documented */1469 }1470 /* assume bq27xxx_battery_update() is called hereafter */1471}1472 1473static void bq27xxx_battery_settings(struct bq27xxx_device_info *di)1474{1475 struct power_supply_battery_info *info;1476 unsigned int min, max;1477 1478 if (power_supply_get_battery_info(di->bat, &info) < 0)1479 return;1480 1481 if (!di->dm_regs) {1482 dev_warn(di->dev, "data memory update not supported for chip\n");1483 return;1484 }1485 1486 if (info->energy_full_design_uwh != info->charge_full_design_uah) {1487 if (info->energy_full_design_uwh == -EINVAL)1488 dev_warn(di->dev, "missing battery:energy-full-design-microwatt-hours\n");1489 else if (info->charge_full_design_uah == -EINVAL)1490 dev_warn(di->dev, "missing battery:charge-full-design-microamp-hours\n");1491 }1492 1493 /* assume min == 0 */1494 max = di->dm_regs[BQ27XXX_DM_DESIGN_ENERGY].max;1495 if (info->energy_full_design_uwh > max * 1000) {1496 dev_err(di->dev, "invalid battery:energy-full-design-microwatt-hours %d\n",1497 info->energy_full_design_uwh);1498 info->energy_full_design_uwh = -EINVAL;1499 }1500 1501 /* assume min == 0 */1502 max = di->dm_regs[BQ27XXX_DM_DESIGN_CAPACITY].max;1503 if (info->charge_full_design_uah > max * 1000) {1504 dev_err(di->dev, "invalid battery:charge-full-design-microamp-hours %d\n",1505 info->charge_full_design_uah);1506 info->charge_full_design_uah = -EINVAL;1507 }1508 1509 min = di->dm_regs[BQ27XXX_DM_TERMINATE_VOLTAGE].min;1510 max = di->dm_regs[BQ27XXX_DM_TERMINATE_VOLTAGE].max;1511 if ((info->voltage_min_design_uv < min * 1000 ||1512 info->voltage_min_design_uv > max * 1000) &&1513 info->voltage_min_design_uv != -EINVAL) {1514 dev_err(di->dev, "invalid battery:voltage-min-design-microvolt %d\n",1515 info->voltage_min_design_uv);1516 info->voltage_min_design_uv = -EINVAL;1517 }1518 1519 if ((info->energy_full_design_uwh != -EINVAL &&1520 info->charge_full_design_uah != -EINVAL) ||1521 info->voltage_min_design_uv != -EINVAL)1522 bq27xxx_battery_set_config(di, info);1523}1524 1525/*1526 * Return the battery State-of-Charge1527 * Or < 0 if something fails.1528 */1529static int bq27xxx_battery_read_soc(struct bq27xxx_device_info *di)1530{1531 int soc;1532 1533 if (di->opts & BQ27XXX_O_SOC_SI)1534 soc = bq27xxx_read(di, BQ27XXX_REG_SOC, true);1535 else1536 soc = bq27xxx_read(di, BQ27XXX_REG_SOC, false);1537 1538 if (soc < 0)1539 dev_dbg(di->dev, "error reading State-of-Charge\n");1540 1541 return soc;1542}1543 1544/*1545 * Return a battery charge value in µAh1546 * Or < 0 if something fails.1547 */1548static int bq27xxx_battery_read_charge(struct bq27xxx_device_info *di, u8 reg,1549 union power_supply_propval *val)1550{1551 int charge;1552 1553 charge = bq27xxx_read(di, reg, false);1554 if (charge < 0) {1555 dev_dbg(di->dev, "error reading charge register %02x: %d\n",1556 reg, charge);1557 return charge;1558 }1559 1560 if (di->opts & BQ27XXX_O_ZERO)1561 charge *= BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;1562 else1563 charge *= 1000;1564 1565 val->intval = charge;1566 1567 return 0;1568}1569 1570/*1571 * Return the battery Nominal available capacity in µAh1572 * Or < 0 if something fails.1573 */1574static inline int bq27xxx_battery_read_nac(struct bq27xxx_device_info *di,1575 union power_supply_propval *val)1576{1577 return bq27xxx_battery_read_charge(di, BQ27XXX_REG_NAC, val);1578}1579 1580/*1581 * Return the battery Remaining Capacity in µAh1582 * Or < 0 if something fails.1583 */1584static inline int bq27xxx_battery_read_rc(struct bq27xxx_device_info *di,1585 union power_supply_propval *val)1586{1587 return bq27xxx_battery_read_charge(di, BQ27XXX_REG_RC, val);1588}1589 1590/*1591 * Return the battery Full Charge Capacity in µAh1592 * Or < 0 if something fails.1593 */1594static inline int bq27xxx_battery_read_fcc(struct bq27xxx_device_info *di,1595 union power_supply_propval *val)1596{1597 return bq27xxx_battery_read_charge(di, BQ27XXX_REG_FCC, val);1598}1599 1600/*1601 * Return the Design Capacity in µAh1602 * Or < 0 if something fails.1603 */1604static int bq27xxx_battery_read_dcap(struct bq27xxx_device_info *di,1605 union power_supply_propval *val)1606{1607 int dcap;1608 1609 /* We only have to read charge design full once */1610 if (di->charge_design_full > 0) {1611 val->intval = di->charge_design_full;1612 return 0;1613 }1614 1615 if (di->opts & BQ27XXX_O_ZERO)1616 dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, true);1617 else1618 dcap = bq27xxx_read(di, BQ27XXX_REG_DCAP, false);1619 1620 if (dcap < 0) {1621 dev_dbg(di->dev, "error reading design capacity\n");1622 return dcap;1623 }1624 1625 if (di->opts & BQ27XXX_O_ZERO)1626 dcap = (dcap << 8) * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;1627 else1628 dcap *= 1000;1629 1630 /* Save for later reads */1631 di->charge_design_full = dcap;1632 1633 val->intval = dcap;1634 1635 return 0;1636}1637 1638/*1639 * Return the battery Available energy in µWh1640 * Or < 0 if something fails.1641 */1642static int bq27xxx_battery_read_energy(struct bq27xxx_device_info *di,1643 union power_supply_propval *val)1644{1645 int ae;1646 1647 ae = bq27xxx_read(di, BQ27XXX_REG_AE, false);1648 if (ae < 0) {1649 dev_dbg(di->dev, "error reading available energy\n");1650 return ae;1651 }1652 1653 if (di->opts & BQ27XXX_O_ZERO)1654 ae *= BQ27XXX_POWER_CONSTANT / BQ27XXX_RS;1655 else1656 ae *= 1000;1657 1658 val->intval = ae;1659 1660 return 0;1661}1662 1663/*1664 * Return the battery temperature in tenths of degree Celsius1665 * Or < 0 if something fails.1666 */1667static int bq27xxx_battery_read_temperature(struct bq27xxx_device_info *di,1668 union power_supply_propval *val)1669{1670 int temp;1671 1672 temp = bq27xxx_read(di, BQ27XXX_REG_TEMP, false);1673 if (temp < 0) {1674 dev_err(di->dev, "error reading temperature\n");1675 return temp;1676 }1677 1678 if (di->opts & BQ27XXX_O_ZERO)1679 temp = 5 * temp / 2;1680 1681 /* Convert decidegree Kelvin to Celsius */1682 temp -= 2731;1683 1684 val->intval = temp;1685 1686 return 0;1687}1688 1689/*1690 * Return the battery Cycle count total1691 * Or < 0 if something fails.1692 */1693static int bq27xxx_battery_read_cyct(struct bq27xxx_device_info *di,1694 union power_supply_propval *val)1695{1696 int cyct;1697 1698 cyct = bq27xxx_read(di, BQ27XXX_REG_CYCT, false);1699 if (cyct < 0)1700 dev_err(di->dev, "error reading cycle count total\n");1701 1702 val->intval = cyct;1703 1704 return 0;1705}1706 1707/*1708 * Read a time register.1709 * Return < 0 if something fails.1710 */1711static int bq27xxx_battery_read_time(struct bq27xxx_device_info *di, u8 reg,1712 union power_supply_propval *val)1713{1714 int tval;1715 1716 tval = bq27xxx_read(di, reg, false);1717 if (tval < 0) {1718 dev_dbg(di->dev, "error reading time register %02x: %d\n",1719 reg, tval);1720 return tval;1721 }1722 1723 if (tval == 65535)1724 return -ENODATA;1725 1726 val->intval = tval * 60;1727 1728 return 0;1729}1730 1731/*1732 * Returns true if a battery over temperature condition is detected1733 */1734static bool bq27xxx_battery_overtemp(struct bq27xxx_device_info *di, u16 flags)1735{1736 if (di->opts & BQ27XXX_O_OTDC)1737 return flags & (BQ27XXX_FLAG_OTC | BQ27XXX_FLAG_OTD);1738 if (di->opts & BQ27XXX_O_UTOT)1739 return flags & BQ27XXX_FLAG_OT;1740 1741 return false;1742}1743 1744/*1745 * Returns true if a battery under temperature condition is detected1746 */1747static bool bq27xxx_battery_undertemp(struct bq27xxx_device_info *di, u16 flags)1748{1749 if (di->opts & BQ27XXX_O_UTOT)1750 return flags & BQ27XXX_FLAG_UT;1751 1752 return false;1753}1754 1755/*1756 * Returns true if a low state of charge condition is detected1757 */1758static bool bq27xxx_battery_dead(struct bq27xxx_device_info *di, u16 flags)1759{1760 if (di->opts & BQ27XXX_O_ZERO)1761 return flags & (BQ27000_FLAG_EDV1 | BQ27000_FLAG_EDVF);1762 else if (di->opts & BQ27Z561_O_BITS)1763 return flags & BQ27Z561_FLAG_FDC;1764 else1765 return flags & (BQ27XXX_FLAG_SOC1 | BQ27XXX_FLAG_SOCF);1766}1767 1768/*1769 * Returns true if reported battery capacity is inaccurate1770 */1771static bool bq27xxx_battery_capacity_inaccurate(struct bq27xxx_device_info *di,1772 u16 flags)1773{1774 if (di->opts & BQ27XXX_O_HAS_CI)1775 return (flags & BQ27000_FLAG_CI);1776 else1777 return false;1778}1779 1780static int bq27xxx_battery_read_health(struct bq27xxx_device_info *di,1781 union power_supply_propval *val)1782{1783 int health;1784 1785 /* Unlikely but important to return first */1786 if (unlikely(bq27xxx_battery_overtemp(di, di->cache.flags)))1787 health = POWER_SUPPLY_HEALTH_OVERHEAT;1788 else if (unlikely(bq27xxx_battery_undertemp(di, di->cache.flags)))1789 health = POWER_SUPPLY_HEALTH_COLD;1790 else if (unlikely(bq27xxx_battery_dead(di, di->cache.flags)))1791 health = POWER_SUPPLY_HEALTH_DEAD;1792 else if (unlikely(bq27xxx_battery_capacity_inaccurate(di, di->cache.flags)))1793 health = POWER_SUPPLY_HEALTH_CALIBRATION_REQUIRED;1794 else1795 health = POWER_SUPPLY_HEALTH_GOOD;1796 1797 val->intval = health;1798 1799 return 0;1800}1801 1802static bool bq27xxx_battery_is_full(struct bq27xxx_device_info *di, int flags)1803{1804 if (di->opts & BQ27XXX_O_ZERO)1805 return (flags & BQ27000_FLAG_FC);1806 else if (di->opts & BQ27Z561_O_BITS)1807 return (flags & BQ27Z561_FLAG_FC);1808 else1809 return (flags & BQ27XXX_FLAG_FC);1810}1811 1812/*1813 * Return the battery average current in µA and the status1814 * Note that current can be negative signed as well1815 * Or 0 if something fails.1816 */1817static int bq27xxx_battery_current_and_status(1818 struct bq27xxx_device_info *di,1819 union power_supply_propval *val_curr,1820 union power_supply_propval *val_status,1821 struct bq27xxx_reg_cache *cache)1822{1823 bool single_flags = (di->opts & BQ27XXX_O_ZERO);1824 int curr;1825 int flags;1826 1827 curr = bq27xxx_read(di, BQ27XXX_REG_AI, false);1828 if (curr < 0) {1829 dev_err(di->dev, "error reading current\n");1830 return curr;1831 }1832 1833 if (cache) {1834 flags = cache->flags;1835 } else {1836 flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, single_flags);1837 if (flags < 0) {1838 dev_err(di->dev, "error reading flags\n");1839 return flags;1840 }1841 }1842 1843 if (di->opts & BQ27XXX_O_ZERO) {1844 if (!(flags & BQ27000_FLAG_CHGS)) {1845 dev_dbg(di->dev, "negative current!\n");1846 curr = -curr;1847 }1848 1849 curr = curr * BQ27XXX_CURRENT_CONSTANT / BQ27XXX_RS;1850 } else {1851 /* Other gauges return signed value */1852 curr = (int)((s16)curr) * 1000;1853 }1854 1855 if (val_curr)1856 val_curr->intval = curr;1857 1858 if (val_status) {1859 if (bq27xxx_battery_is_full(di, flags))1860 val_status->intval = POWER_SUPPLY_STATUS_FULL;1861 else if (curr > 0)1862 val_status->intval = POWER_SUPPLY_STATUS_CHARGING;1863 else if (curr < 0)1864 val_status->intval = POWER_SUPPLY_STATUS_DISCHARGING;1865 else1866 val_status->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;1867 }1868 1869 return 0;1870}1871 1872static void bq27xxx_battery_update_unlocked(struct bq27xxx_device_info *di)1873{1874 union power_supply_propval status = di->last_status;1875 struct bq27xxx_reg_cache cache = {0, };1876 bool has_singe_flag = di->opts & BQ27XXX_O_ZERO;1877 1878 cache.flags = bq27xxx_read(di, BQ27XXX_REG_FLAGS, has_singe_flag);1879 if ((cache.flags & 0xff) == 0xff)1880 cache.flags = -1; /* read error */1881 if (cache.flags >= 0) {1882 cache.capacity = bq27xxx_battery_read_soc(di);1883 di->cache.flags = cache.flags;1884 1885 /*1886 * On gauges with signed current reporting the current must be1887 * checked to detect charging <-> discharging status changes.1888 */1889 if (!(di->opts & BQ27XXX_O_ZERO))1890 bq27xxx_battery_current_and_status(di, NULL, &status, &cache);1891 }1892 1893 if ((di->cache.capacity != cache.capacity) ||1894 (di->cache.flags != cache.flags) ||1895 (di->last_status.intval != status.intval)) {1896 di->last_status.intval = status.intval;1897 power_supply_changed(di->bat);1898 }1899 1900 if (memcmp(&di->cache, &cache, sizeof(cache)) != 0)1901 di->cache = cache;1902 1903 di->last_update = jiffies;1904 1905 if (!di->removed && poll_interval > 0)1906 mod_delayed_work(system_wq, &di->work, poll_interval * HZ);1907}1908 1909void bq27xxx_battery_update(struct bq27xxx_device_info *di)1910{1911 mutex_lock(&di->lock);1912 bq27xxx_battery_update_unlocked(di);1913 mutex_unlock(&di->lock);1914}1915EXPORT_SYMBOL_GPL(bq27xxx_battery_update);1916 1917static void bq27xxx_battery_poll(struct work_struct *work)1918{1919 struct bq27xxx_device_info *di =1920 container_of(work, struct bq27xxx_device_info,1921 work.work);1922 1923 bq27xxx_battery_update(di);1924}1925 1926/*1927 * Get the average power in µW1928 * Return < 0 if something fails.1929 */1930static int bq27xxx_battery_pwr_avg(struct bq27xxx_device_info *di,1931 union power_supply_propval *val)1932{1933 int power;1934 1935 power = bq27xxx_read(di, BQ27XXX_REG_AP, false);1936 if (power < 0) {1937 dev_err(di->dev,1938 "error reading average power register %02x: %d\n",1939 BQ27XXX_REG_AP, power);1940 return power;1941 }1942 1943 if (di->opts & BQ27XXX_O_ZERO)1944 val->intval = (power * BQ27XXX_POWER_CONSTANT) / BQ27XXX_RS;1945 else1946 /* Other gauges return a signed value in units of 10mW */1947 val->intval = (int)((s16)power) * 10000;1948 1949 return 0;1950}1951 1952static int bq27xxx_battery_capacity_level(struct bq27xxx_device_info *di,1953 union power_supply_propval *val)1954{1955 int level;1956 1957 if (di->opts & BQ27XXX_O_ZERO) {1958 if (di->cache.flags & BQ27000_FLAG_FC)1959 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;1960 else if (di->cache.flags & BQ27000_FLAG_EDVF)1961 level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;1962 else if (di->cache.flags & BQ27000_FLAG_EDV1)1963 level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;1964 else1965 level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;1966 } else if (di->opts & BQ27Z561_O_BITS) {1967 if (di->cache.flags & BQ27Z561_FLAG_FC)1968 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;1969 else if (di->cache.flags & BQ27Z561_FLAG_FDC)1970 level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;1971 else1972 level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;1973 } else {1974 if (di->cache.flags & BQ27XXX_FLAG_FC)1975 level = POWER_SUPPLY_CAPACITY_LEVEL_FULL;1976 else if (di->cache.flags & BQ27XXX_FLAG_SOCF)1977 level = POWER_SUPPLY_CAPACITY_LEVEL_CRITICAL;1978 else if (di->cache.flags & BQ27XXX_FLAG_SOC1)1979 level = POWER_SUPPLY_CAPACITY_LEVEL_LOW;1980 else1981 level = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;1982 }1983 1984 val->intval = level;1985 1986 return 0;1987}1988 1989/*1990 * Return the battery Voltage in millivolts1991 * Or < 0 if something fails.1992 */1993static int bq27xxx_battery_voltage(struct bq27xxx_device_info *di,1994 union power_supply_propval *val)1995{1996 int volt;1997 1998 volt = bq27xxx_read(di, BQ27XXX_REG_VOLT, false);1999 if (volt < 0) {2000 dev_err(di->dev, "error reading voltage\n");2001 return volt;2002 }2003 2004 val->intval = volt * 1000;2005 2006 return 0;2007}2008 2009static int bq27xxx_simple_value(int value,2010 union power_supply_propval *val)2011{2012 if (value < 0)2013 return value;2014 2015 val->intval = value;2016 2017 return 0;2018}2019 2020static int bq27xxx_battery_get_property(struct power_supply *psy,2021 enum power_supply_property psp,2022 union power_supply_propval *val)2023{2024 int ret = 0;2025 struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);2026 2027 mutex_lock(&di->lock);2028 if (time_is_before_jiffies(di->last_update + 5 * HZ))2029 bq27xxx_battery_update_unlocked(di);2030 mutex_unlock(&di->lock);2031 2032 if (psp != POWER_SUPPLY_PROP_PRESENT && di->cache.flags < 0)2033 return -ENODEV;2034 2035 switch (psp) {2036 case POWER_SUPPLY_PROP_STATUS:2037 ret = bq27xxx_battery_current_and_status(di, NULL, val, NULL);2038 break;2039 case POWER_SUPPLY_PROP_VOLTAGE_NOW:2040 ret = bq27xxx_battery_voltage(di, val);2041 break;2042 case POWER_SUPPLY_PROP_PRESENT:2043 val->intval = di->cache.flags < 0 ? 0 : 1;2044 break;2045 case POWER_SUPPLY_PROP_CURRENT_NOW:2046 ret = bq27xxx_battery_current_and_status(di, val, NULL, NULL);2047 break;2048 case POWER_SUPPLY_PROP_CAPACITY:2049 ret = bq27xxx_simple_value(di->cache.capacity, val);2050 break;2051 case POWER_SUPPLY_PROP_CAPACITY_LEVEL:2052 ret = bq27xxx_battery_capacity_level(di, val);2053 break;2054 case POWER_SUPPLY_PROP_TEMP:2055 ret = bq27xxx_battery_read_temperature(di, val);2056 break;2057 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:2058 ret = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTE, val);2059 break;2060 case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:2061 ret = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTECP, val);2062 break;2063 case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:2064 ret = bq27xxx_battery_read_time(di, BQ27XXX_REG_TTF, val);2065 break;2066 case POWER_SUPPLY_PROP_TECHNOLOGY:2067 if (di->opts & BQ27XXX_O_MUL_CHEM)2068 val->intval = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;2069 else2070 val->intval = POWER_SUPPLY_TECHNOLOGY_LION;2071 break;2072 case POWER_SUPPLY_PROP_CHARGE_NOW:2073 if (di->regs[BQ27XXX_REG_NAC] != INVALID_REG_ADDR)2074 ret = bq27xxx_battery_read_nac(di, val);2075 else2076 ret = bq27xxx_battery_read_rc(di, val);2077 break;2078 case POWER_SUPPLY_PROP_CHARGE_FULL:2079 ret = bq27xxx_battery_read_fcc(di, val);2080 break;2081 case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:2082 ret = bq27xxx_battery_read_dcap(di, val);2083 break;2084 /*2085 * TODO: Implement these to make registers set from2086 * power_supply_battery_info visible in sysfs.2087 */2088 case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:2089 case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:2090 return -EINVAL;2091 case POWER_SUPPLY_PROP_CYCLE_COUNT:2092 ret = bq27xxx_battery_read_cyct(di, val);2093 break;2094 case POWER_SUPPLY_PROP_ENERGY_NOW:2095 ret = bq27xxx_battery_read_energy(di, val);2096 break;2097 case POWER_SUPPLY_PROP_POWER_AVG:2098 ret = bq27xxx_battery_pwr_avg(di, val);2099 break;2100 case POWER_SUPPLY_PROP_HEALTH:2101 ret = bq27xxx_battery_read_health(di, val);2102 break;2103 case POWER_SUPPLY_PROP_MANUFACTURER:2104 val->strval = BQ27XXX_MANUFACTURER;2105 break;2106 default:2107 return -EINVAL;2108 }2109 2110 return ret;2111}2112 2113static void bq27xxx_external_power_changed(struct power_supply *psy)2114{2115 struct bq27xxx_device_info *di = power_supply_get_drvdata(psy);2116 2117 /* After charger plug in/out wait 0.5s for things to stabilize */2118 mod_delayed_work(system_wq, &di->work, HZ / 2);2119}2120 2121static void bq27xxx_battery_mutex_destroy(void *data)2122{2123 struct mutex *lock = data;2124 2125 mutex_destroy(lock);2126}2127 2128int bq27xxx_battery_setup(struct bq27xxx_device_info *di)2129{2130 struct power_supply_desc *psy_desc;2131 struct power_supply_config psy_cfg = {2132 .of_node = di->dev->of_node,2133 .drv_data = di,2134 };2135 int ret;2136 2137 INIT_DELAYED_WORK(&di->work, bq27xxx_battery_poll);2138 mutex_init(&di->lock);2139 ret = devm_add_action_or_reset(di->dev, bq27xxx_battery_mutex_destroy,2140 &di->lock);2141 if (ret)2142 return ret;2143 2144 di->regs = bq27xxx_chip_data[di->chip].regs;2145 di->unseal_key = bq27xxx_chip_data[di->chip].unseal_key;2146 di->dm_regs = bq27xxx_chip_data[di->chip].dm_regs;2147 di->opts = bq27xxx_chip_data[di->chip].opts;2148 2149 psy_desc = devm_kzalloc(di->dev, sizeof(*psy_desc), GFP_KERNEL);2150 if (!psy_desc)2151 return -ENOMEM;2152 2153 psy_desc->name = di->name;2154 psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;2155 psy_desc->properties = bq27xxx_chip_data[di->chip].props;2156 psy_desc->num_properties = bq27xxx_chip_data[di->chip].props_size;2157 psy_desc->get_property = bq27xxx_battery_get_property;2158 psy_desc->external_power_changed = bq27xxx_external_power_changed;2159 2160 di->bat = devm_power_supply_register_no_ws(di->dev, psy_desc, &psy_cfg);2161 if (IS_ERR(di->bat))2162 return dev_err_probe(di->dev, PTR_ERR(di->bat),2163 "failed to register battery\n");2164 2165 bq27xxx_battery_settings(di);2166 bq27xxx_battery_update(di);2167 2168 mutex_lock(&bq27xxx_list_lock);2169 list_add(&di->list, &bq27xxx_battery_devices);2170 mutex_unlock(&bq27xxx_list_lock);2171 2172 return 0;2173}2174EXPORT_SYMBOL_GPL(bq27xxx_battery_setup);2175 2176void bq27xxx_battery_teardown(struct bq27xxx_device_info *di)2177{2178 mutex_lock(&bq27xxx_list_lock);2179 list_del(&di->list);2180 mutex_unlock(&bq27xxx_list_lock);2181 2182 /* Set removed to avoid bq27xxx_battery_update() re-queuing the work */2183 mutex_lock(&di->lock);2184 di->removed = true;2185 mutex_unlock(&di->lock);2186 2187 cancel_delayed_work_sync(&di->work);2188}2189EXPORT_SYMBOL_GPL(bq27xxx_battery_teardown);2190 2191#ifdef CONFIG_PM_SLEEP2192static int bq27xxx_battery_suspend(struct device *dev)2193{2194 struct bq27xxx_device_info *di = dev_get_drvdata(dev);2195 2196 cancel_delayed_work(&di->work);2197 return 0;2198}2199 2200static int bq27xxx_battery_resume(struct device *dev)2201{2202 struct bq27xxx_device_info *di = dev_get_drvdata(dev);2203 2204 schedule_delayed_work(&di->work, 0);2205 return 0;2206}2207#endif /* CONFIG_PM_SLEEP */2208 2209SIMPLE_DEV_PM_OPS(bq27xxx_battery_battery_pm_ops,2210 bq27xxx_battery_suspend, bq27xxx_battery_resume);2211EXPORT_SYMBOL_GPL(bq27xxx_battery_battery_pm_ops);2212 2213MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");2214MODULE_DESCRIPTION("BQ27xxx battery monitor driver");2215MODULE_LICENSE("GPL");2216