max77976_charger.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * max77976_charger.c - Driver for the Maxim MAX77976 battery charger
  4. *
  5. * Copyright (C) 2021 Luca Ceresoli
  6. * Author: Luca Ceresoli <[email protected]>
  7. */
  8. #include <linux/i2c.h>
  9. #include <linux/module.h>
  10. #include <linux/power_supply.h>
  11. #include <linux/regmap.h>
  12. #define MAX77976_DRIVER_NAME "max77976-charger"
  13. #define MAX77976_CHIP_ID 0x76
  14. static const char *max77976_manufacturer = "Maxim Integrated";
  15. static const char *max77976_model = "MAX77976";
  16. /* --------------------------------------------------------------------------
  17. * Register map
  18. */
  19. #define MAX77976_REG_CHIP_ID 0x00
  20. #define MAX77976_REG_CHIP_REVISION 0x01
  21. #define MAX77976_REG_CHG_INT_OK 0x12
  22. #define MAX77976_REG_CHG_DETAILS_01 0x14
  23. #define MAX77976_REG_CHG_CNFG_00 0x16
  24. #define MAX77976_REG_CHG_CNFG_02 0x18
  25. #define MAX77976_REG_CHG_CNFG_06 0x1c
  26. #define MAX77976_REG_CHG_CNFG_09 0x1f
  27. /* CHG_DETAILS_01.CHG_DTLS values */
  28. enum max77976_charging_state {
  29. MAX77976_CHARGING_PREQUALIFICATION = 0x0,
  30. MAX77976_CHARGING_FAST_CONST_CURRENT,
  31. MAX77976_CHARGING_FAST_CONST_VOLTAGE,
  32. MAX77976_CHARGING_TOP_OFF,
  33. MAX77976_CHARGING_DONE,
  34. MAX77976_CHARGING_RESERVED_05,
  35. MAX77976_CHARGING_TIMER_FAULT,
  36. MAX77976_CHARGING_SUSPENDED_QBATT_OFF,
  37. MAX77976_CHARGING_OFF,
  38. MAX77976_CHARGING_RESERVED_09,
  39. MAX77976_CHARGING_THERMAL_SHUTDOWN,
  40. MAX77976_CHARGING_WATCHDOG_EXPIRED,
  41. MAX77976_CHARGING_SUSPENDED_JEITA,
  42. MAX77976_CHARGING_SUSPENDED_THM_REMOVAL,
  43. MAX77976_CHARGING_SUSPENDED_PIN,
  44. MAX77976_CHARGING_RESERVED_0F,
  45. };
  46. /* CHG_DETAILS_01.BAT_DTLS values */
  47. enum max77976_battery_state {
  48. MAX77976_BATTERY_BATTERY_REMOVAL = 0x0,
  49. MAX77976_BATTERY_PREQUALIFICATION,
  50. MAX77976_BATTERY_TIMER_FAULT,
  51. MAX77976_BATTERY_REGULAR_VOLTAGE,
  52. MAX77976_BATTERY_LOW_VOLTAGE,
  53. MAX77976_BATTERY_OVERVOLTAGE,
  54. MAX77976_BATTERY_RESERVED,
  55. MAX77976_BATTERY_BATTERY_ONLY, // No valid adapter is present
  56. };
  57. /* CHG_CNFG_00.MODE values */
  58. enum max77976_mode {
  59. MAX77976_MODE_CHARGER_BUCK = 0x5,
  60. MAX77976_MODE_BOOST = 0x9,
  61. };
  62. /* CHG_CNFG_02.CHG_CC: charge current limit, 100..5500 mA, 50 mA steps */
  63. #define MAX77976_CHG_CC_STEP 50000U
  64. #define MAX77976_CHG_CC_MIN 100000U
  65. #define MAX77976_CHG_CC_MAX 5500000U
  66. /* CHG_CNFG_09.CHGIN_ILIM: input current limit, 100..3200 mA, 100 mA steps */
  67. #define MAX77976_CHGIN_ILIM_STEP 100000U
  68. #define MAX77976_CHGIN_ILIM_MIN 100000U
  69. #define MAX77976_CHGIN_ILIM_MAX 3200000U
  70. enum max77976_field_idx {
  71. VERSION, REVISION, /* CHIP_REVISION */
  72. CHGIN_OK, /* CHG_INT_OK */
  73. BAT_DTLS, CHG_DTLS, /* CHG_DETAILS_01 */
  74. MODE, /* CHG_CNFG_00 */
  75. CHG_CC, /* CHG_CNFG_02 */
  76. CHGPROT, /* CHG_CNFG_06 */
  77. CHGIN_ILIM, /* CHG_CNFG_09 */
  78. MAX77976_N_REGMAP_FIELDS
  79. };
  80. static const struct reg_field max77976_reg_field[MAX77976_N_REGMAP_FIELDS] = {
  81. [VERSION] = REG_FIELD(MAX77976_REG_CHIP_REVISION, 4, 7),
  82. [REVISION] = REG_FIELD(MAX77976_REG_CHIP_REVISION, 0, 3),
  83. [CHGIN_OK] = REG_FIELD(MAX77976_REG_CHG_INT_OK, 6, 6),
  84. [CHG_DTLS] = REG_FIELD(MAX77976_REG_CHG_DETAILS_01, 0, 3),
  85. [BAT_DTLS] = REG_FIELD(MAX77976_REG_CHG_DETAILS_01, 4, 6),
  86. [MODE] = REG_FIELD(MAX77976_REG_CHG_CNFG_00, 0, 3),
  87. [CHG_CC] = REG_FIELD(MAX77976_REG_CHG_CNFG_02, 0, 6),
  88. [CHGPROT] = REG_FIELD(MAX77976_REG_CHG_CNFG_06, 2, 3),
  89. [CHGIN_ILIM] = REG_FIELD(MAX77976_REG_CHG_CNFG_09, 0, 5),
  90. };
  91. static const struct regmap_config max77976_regmap_config = {
  92. .reg_bits = 8,
  93. .val_bits = 8,
  94. .max_register = 0x24,
  95. };
  96. /* --------------------------------------------------------------------------
  97. * Data structures
  98. */
  99. struct max77976 {
  100. struct i2c_client *client;
  101. struct regmap *regmap;
  102. struct regmap_field *rfield[MAX77976_N_REGMAP_FIELDS];
  103. };
  104. /* --------------------------------------------------------------------------
  105. * power_supply properties
  106. */
  107. static int max77976_get_status(struct max77976 *chg, int *val)
  108. {
  109. unsigned int regval;
  110. int err;
  111. err = regmap_field_read(chg->rfield[CHG_DTLS], &regval);
  112. if (err < 0)
  113. return err;
  114. switch (regval) {
  115. case MAX77976_CHARGING_PREQUALIFICATION:
  116. case MAX77976_CHARGING_FAST_CONST_CURRENT:
  117. case MAX77976_CHARGING_FAST_CONST_VOLTAGE:
  118. case MAX77976_CHARGING_TOP_OFF:
  119. *val = POWER_SUPPLY_STATUS_CHARGING;
  120. break;
  121. case MAX77976_CHARGING_DONE:
  122. *val = POWER_SUPPLY_STATUS_FULL;
  123. break;
  124. case MAX77976_CHARGING_TIMER_FAULT:
  125. case MAX77976_CHARGING_SUSPENDED_QBATT_OFF:
  126. case MAX77976_CHARGING_SUSPENDED_JEITA:
  127. case MAX77976_CHARGING_SUSPENDED_THM_REMOVAL:
  128. case MAX77976_CHARGING_SUSPENDED_PIN:
  129. *val = POWER_SUPPLY_STATUS_NOT_CHARGING;
  130. break;
  131. case MAX77976_CHARGING_OFF:
  132. case MAX77976_CHARGING_THERMAL_SHUTDOWN:
  133. case MAX77976_CHARGING_WATCHDOG_EXPIRED:
  134. *val = POWER_SUPPLY_STATUS_DISCHARGING;
  135. break;
  136. default:
  137. *val = POWER_SUPPLY_STATUS_UNKNOWN;
  138. }
  139. return 0;
  140. }
  141. static int max77976_get_charge_type(struct max77976 *chg, int *val)
  142. {
  143. unsigned int regval;
  144. int err;
  145. err = regmap_field_read(chg->rfield[CHG_DTLS], &regval);
  146. if (err < 0)
  147. return err;
  148. switch (regval) {
  149. case MAX77976_CHARGING_PREQUALIFICATION:
  150. *val = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
  151. break;
  152. case MAX77976_CHARGING_FAST_CONST_CURRENT:
  153. case MAX77976_CHARGING_FAST_CONST_VOLTAGE:
  154. *val = POWER_SUPPLY_CHARGE_TYPE_FAST;
  155. break;
  156. case MAX77976_CHARGING_TOP_OFF:
  157. *val = POWER_SUPPLY_CHARGE_TYPE_STANDARD;
  158. break;
  159. case MAX77976_CHARGING_DONE:
  160. case MAX77976_CHARGING_TIMER_FAULT:
  161. case MAX77976_CHARGING_SUSPENDED_QBATT_OFF:
  162. case MAX77976_CHARGING_OFF:
  163. case MAX77976_CHARGING_THERMAL_SHUTDOWN:
  164. case MAX77976_CHARGING_WATCHDOG_EXPIRED:
  165. case MAX77976_CHARGING_SUSPENDED_JEITA:
  166. case MAX77976_CHARGING_SUSPENDED_THM_REMOVAL:
  167. case MAX77976_CHARGING_SUSPENDED_PIN:
  168. *val = POWER_SUPPLY_CHARGE_TYPE_NONE;
  169. break;
  170. default:
  171. *val = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
  172. }
  173. return 0;
  174. }
  175. static int max77976_get_health(struct max77976 *chg, int *val)
  176. {
  177. unsigned int regval;
  178. int err;
  179. err = regmap_field_read(chg->rfield[BAT_DTLS], &regval);
  180. if (err < 0)
  181. return err;
  182. switch (regval) {
  183. case MAX77976_BATTERY_BATTERY_REMOVAL:
  184. *val = POWER_SUPPLY_HEALTH_NO_BATTERY;
  185. break;
  186. case MAX77976_BATTERY_LOW_VOLTAGE:
  187. case MAX77976_BATTERY_REGULAR_VOLTAGE:
  188. *val = POWER_SUPPLY_HEALTH_GOOD;
  189. break;
  190. case MAX77976_BATTERY_TIMER_FAULT:
  191. *val = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
  192. break;
  193. case MAX77976_BATTERY_OVERVOLTAGE:
  194. *val = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
  195. break;
  196. case MAX77976_BATTERY_PREQUALIFICATION:
  197. case MAX77976_BATTERY_BATTERY_ONLY:
  198. *val = POWER_SUPPLY_HEALTH_UNKNOWN;
  199. break;
  200. default:
  201. *val = POWER_SUPPLY_HEALTH_UNKNOWN;
  202. }
  203. return 0;
  204. }
  205. static int max77976_get_online(struct max77976 *chg, int *val)
  206. {
  207. unsigned int regval;
  208. int err;
  209. err = regmap_field_read(chg->rfield[CHGIN_OK], &regval);
  210. if (err < 0)
  211. return err;
  212. *val = (regval ? 1 : 0);
  213. return 0;
  214. }
  215. static int max77976_get_integer(struct max77976 *chg, enum max77976_field_idx fidx,
  216. unsigned int clamp_min, unsigned int clamp_max,
  217. unsigned int mult, int *val)
  218. {
  219. unsigned int regval;
  220. int err;
  221. err = regmap_field_read(chg->rfield[fidx], &regval);
  222. if (err < 0)
  223. return err;
  224. *val = clamp_val(regval * mult, clamp_min, clamp_max);
  225. return 0;
  226. }
  227. static int max77976_set_integer(struct max77976 *chg, enum max77976_field_idx fidx,
  228. unsigned int clamp_min, unsigned int clamp_max,
  229. unsigned int div, int val)
  230. {
  231. unsigned int regval;
  232. regval = clamp_val(val, clamp_min, clamp_max) / div;
  233. return regmap_field_write(chg->rfield[fidx], regval);
  234. }
  235. static int max77976_get_property(struct power_supply *psy,
  236. enum power_supply_property psp,
  237. union power_supply_propval *val)
  238. {
  239. struct max77976 *chg = power_supply_get_drvdata(psy);
  240. int err = 0;
  241. switch (psp) {
  242. case POWER_SUPPLY_PROP_STATUS:
  243. err = max77976_get_status(chg, &val->intval);
  244. break;
  245. case POWER_SUPPLY_PROP_CHARGE_TYPE:
  246. err = max77976_get_charge_type(chg, &val->intval);
  247. break;
  248. case POWER_SUPPLY_PROP_HEALTH:
  249. err = max77976_get_health(chg, &val->intval);
  250. break;
  251. case POWER_SUPPLY_PROP_ONLINE:
  252. err = max77976_get_online(chg, &val->intval);
  253. break;
  254. case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX:
  255. val->intval = MAX77976_CHG_CC_MAX;
  256. break;
  257. case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
  258. err = max77976_get_integer(chg, CHG_CC,
  259. MAX77976_CHG_CC_MIN,
  260. MAX77976_CHG_CC_MAX,
  261. MAX77976_CHG_CC_STEP,
  262. &val->intval);
  263. break;
  264. case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
  265. err = max77976_get_integer(chg, CHGIN_ILIM,
  266. MAX77976_CHGIN_ILIM_MIN,
  267. MAX77976_CHGIN_ILIM_MAX,
  268. MAX77976_CHGIN_ILIM_STEP,
  269. &val->intval);
  270. break;
  271. case POWER_SUPPLY_PROP_MODEL_NAME:
  272. val->strval = max77976_model;
  273. break;
  274. case POWER_SUPPLY_PROP_MANUFACTURER:
  275. val->strval = max77976_manufacturer;
  276. break;
  277. default:
  278. err = -EINVAL;
  279. }
  280. return err;
  281. }
  282. static int max77976_set_property(struct power_supply *psy,
  283. enum power_supply_property psp,
  284. const union power_supply_propval *val)
  285. {
  286. struct max77976 *chg = power_supply_get_drvdata(psy);
  287. int err = 0;
  288. switch (psp) {
  289. case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
  290. err = max77976_set_integer(chg, CHG_CC,
  291. MAX77976_CHG_CC_MIN,
  292. MAX77976_CHG_CC_MAX,
  293. MAX77976_CHG_CC_STEP,
  294. val->intval);
  295. break;
  296. case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
  297. err = max77976_set_integer(chg, CHGIN_ILIM,
  298. MAX77976_CHGIN_ILIM_MIN,
  299. MAX77976_CHGIN_ILIM_MAX,
  300. MAX77976_CHGIN_ILIM_STEP,
  301. val->intval);
  302. break;
  303. default:
  304. err = -EINVAL;
  305. }
  306. return err;
  307. };
  308. static int max77976_property_is_writeable(struct power_supply *psy,
  309. enum power_supply_property psp)
  310. {
  311. switch (psp) {
  312. case POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT:
  313. case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
  314. return true;
  315. default:
  316. return false;
  317. }
  318. }
  319. static enum power_supply_property max77976_psy_props[] = {
  320. POWER_SUPPLY_PROP_STATUS,
  321. POWER_SUPPLY_PROP_CHARGE_TYPE,
  322. POWER_SUPPLY_PROP_HEALTH,
  323. POWER_SUPPLY_PROP_ONLINE,
  324. POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT,
  325. POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX,
  326. POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
  327. POWER_SUPPLY_PROP_MODEL_NAME,
  328. POWER_SUPPLY_PROP_MANUFACTURER,
  329. };
  330. static const struct power_supply_desc max77976_psy_desc = {
  331. .name = MAX77976_DRIVER_NAME,
  332. .type = POWER_SUPPLY_TYPE_USB,
  333. .properties = max77976_psy_props,
  334. .num_properties = ARRAY_SIZE(max77976_psy_props),
  335. .get_property = max77976_get_property,
  336. .set_property = max77976_set_property,
  337. .property_is_writeable = max77976_property_is_writeable,
  338. };
  339. /* --------------------------------------------------------------------------
  340. * Entry point
  341. */
  342. static int max77976_detect(struct max77976 *chg)
  343. {
  344. struct device *dev = &chg->client->dev;
  345. unsigned int id, ver, rev;
  346. int err;
  347. err = regmap_read(chg->regmap, MAX77976_REG_CHIP_ID, &id);
  348. if (err)
  349. return dev_err_probe(dev, err, "cannot read chip ID\n");
  350. if (id != MAX77976_CHIP_ID)
  351. return dev_err_probe(dev, -ENXIO, "unknown model ID 0x%02x\n", id);
  352. err = regmap_field_read(chg->rfield[VERSION], &ver);
  353. if (!err)
  354. err = regmap_field_read(chg->rfield[REVISION], &rev);
  355. if (err)
  356. return dev_err_probe(dev, -ENXIO, "cannot read version/revision\n");
  357. dev_info(dev, "detected model MAX779%02x ver %u rev %u", id, ver, rev);
  358. return 0;
  359. }
  360. static int max77976_configure(struct max77976 *chg)
  361. {
  362. struct device *dev = &chg->client->dev;
  363. int err;
  364. /* Magic value to unlock writing to some registers */
  365. err = regmap_field_write(chg->rfield[CHGPROT], 0x3);
  366. if (err)
  367. goto err;
  368. /*
  369. * Mode 5 = Charger ON, OTG OFF, buck ON, boost OFF.
  370. * Other modes are not implemented by this driver.
  371. */
  372. err = regmap_field_write(chg->rfield[MODE], MAX77976_MODE_CHARGER_BUCK);
  373. if (err)
  374. goto err;
  375. return 0;
  376. err:
  377. return dev_err_probe(dev, err, "error while configuring");
  378. }
  379. static int max77976_probe(struct i2c_client *client)
  380. {
  381. struct device *dev = &client->dev;
  382. struct power_supply_config psy_cfg = {};
  383. struct power_supply *psy;
  384. struct max77976 *chg;
  385. int err;
  386. int i;
  387. chg = devm_kzalloc(dev, sizeof(*chg), GFP_KERNEL);
  388. if (!chg)
  389. return -ENOMEM;
  390. i2c_set_clientdata(client, chg);
  391. psy_cfg.drv_data = chg;
  392. chg->client = client;
  393. chg->regmap = devm_regmap_init_i2c(client, &max77976_regmap_config);
  394. if (IS_ERR(chg->regmap))
  395. return dev_err_probe(dev, PTR_ERR(chg->regmap),
  396. "cannot allocate regmap\n");
  397. for (i = 0; i < MAX77976_N_REGMAP_FIELDS; i++) {
  398. chg->rfield[i] = devm_regmap_field_alloc(dev, chg->regmap,
  399. max77976_reg_field[i]);
  400. if (IS_ERR(chg->rfield[i]))
  401. return dev_err_probe(dev, PTR_ERR(chg->rfield[i]),
  402. "cannot allocate regmap field\n");
  403. }
  404. err = max77976_detect(chg);
  405. if (err)
  406. return err;
  407. err = max77976_configure(chg);
  408. if (err)
  409. return err;
  410. psy = devm_power_supply_register_no_ws(dev, &max77976_psy_desc, &psy_cfg);
  411. if (IS_ERR(psy))
  412. return dev_err_probe(dev, PTR_ERR(psy), "cannot register\n");
  413. return 0;
  414. }
  415. static const struct i2c_device_id max77976_i2c_id[] = {
  416. { MAX77976_DRIVER_NAME, 0 },
  417. { },
  418. };
  419. MODULE_DEVICE_TABLE(i2c, max77976_i2c_id);
  420. static const struct of_device_id max77976_of_id[] = {
  421. { .compatible = "maxim,max77976" },
  422. { },
  423. };
  424. MODULE_DEVICE_TABLE(of, max77976_of_id);
  425. static struct i2c_driver max77976_driver = {
  426. .driver = {
  427. .name = MAX77976_DRIVER_NAME,
  428. .of_match_table = max77976_of_id,
  429. },
  430. .probe_new = max77976_probe,
  431. .id_table = max77976_i2c_id,
  432. };
  433. module_i2c_driver(max77976_driver);
  434. MODULE_AUTHOR("Luca Ceresoli <[email protected]>");
  435. MODULE_DESCRIPTION("Maxim MAX77976 charger driver");
  436. MODULE_LICENSE("GPL v2");