smb347-charger.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294
  1. /*
  2. * Summit Microelectronics SMB347 Battery Charger Driver
  3. *
  4. * Copyright (C) 2011, Intel Corporation
  5. *
  6. * Authors: Bruce E. Robertson <bruce.e.robertson@intel.com>
  7. * Mika Westerberg <mika.westerberg@linux.intel.com>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include <linux/debugfs.h>
  14. #include <linux/gpio.h>
  15. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/i2c.h>
  20. #include <linux/mutex.h>
  21. #include <linux/power_supply.h>
  22. #include <linux/power/smb347-charger.h>
  23. #include <linux/seq_file.h>
  24. /*
  25. * Configuration registers. These are mirrored to volatile RAM and can be
  26. * written once %CMD_A_ALLOW_WRITE is set in %CMD_A register. They will be
  27. * reloaded from non-volatile registers after POR.
  28. */
  29. #define CFG_CHARGE_CURRENT 0x00
  30. #define CFG_CHARGE_CURRENT_FCC_MASK 0xe0
  31. #define CFG_CHARGE_CURRENT_FCC_SHIFT 5
  32. #define CFG_CHARGE_CURRENT_PCC_MASK 0x18
  33. #define CFG_CHARGE_CURRENT_PCC_SHIFT 3
  34. #define CFG_CHARGE_CURRENT_TC_MASK 0x07
  35. #define CFG_CURRENT_LIMIT 0x01
  36. #define CFG_CURRENT_LIMIT_DC_MASK 0xf0
  37. #define CFG_CURRENT_LIMIT_DC_SHIFT 4
  38. #define CFG_CURRENT_LIMIT_USB_MASK 0x0f
  39. #define CFG_FLOAT_VOLTAGE 0x03
  40. #define CFG_FLOAT_VOLTAGE_THRESHOLD_MASK 0xc0
  41. #define CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT 6
  42. #define CFG_STAT 0x05
  43. #define CFG_STAT_DISABLED BIT(5)
  44. #define CFG_STAT_ACTIVE_HIGH BIT(7)
  45. #define CFG_PIN 0x06
  46. #define CFG_PIN_EN_CTRL_MASK 0x60
  47. #define CFG_PIN_EN_CTRL_ACTIVE_HIGH 0x40
  48. #define CFG_PIN_EN_CTRL_ACTIVE_LOW 0x60
  49. #define CFG_PIN_EN_APSD_IRQ BIT(1)
  50. #define CFG_PIN_EN_CHARGER_ERROR BIT(2)
  51. #define CFG_THERM 0x07
  52. #define CFG_THERM_SOFT_HOT_COMPENSATION_MASK 0x03
  53. #define CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT 0
  54. #define CFG_THERM_SOFT_COLD_COMPENSATION_MASK 0x0c
  55. #define CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT 2
  56. #define CFG_THERM_MONITOR_DISABLED BIT(4)
  57. #define CFG_SYSOK 0x08
  58. #define CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED BIT(2)
  59. #define CFG_OTHER 0x09
  60. #define CFG_OTHER_RID_MASK 0xc0
  61. #define CFG_OTHER_RID_ENABLED_AUTO_OTG 0xc0
  62. #define CFG_OTG 0x0a
  63. #define CFG_OTG_TEMP_THRESHOLD_MASK 0x30
  64. #define CFG_OTG_TEMP_THRESHOLD_SHIFT 4
  65. #define CFG_OTG_CC_COMPENSATION_MASK 0xc0
  66. #define CFG_OTG_CC_COMPENSATION_SHIFT 6
  67. #define CFG_TEMP_LIMIT 0x0b
  68. #define CFG_TEMP_LIMIT_SOFT_HOT_MASK 0x03
  69. #define CFG_TEMP_LIMIT_SOFT_HOT_SHIFT 0
  70. #define CFG_TEMP_LIMIT_SOFT_COLD_MASK 0x0c
  71. #define CFG_TEMP_LIMIT_SOFT_COLD_SHIFT 2
  72. #define CFG_TEMP_LIMIT_HARD_HOT_MASK 0x30
  73. #define CFG_TEMP_LIMIT_HARD_HOT_SHIFT 4
  74. #define CFG_TEMP_LIMIT_HARD_COLD_MASK 0xc0
  75. #define CFG_TEMP_LIMIT_HARD_COLD_SHIFT 6
  76. #define CFG_FAULT_IRQ 0x0c
  77. #define CFG_FAULT_IRQ_DCIN_UV BIT(2)
  78. #define CFG_STATUS_IRQ 0x0d
  79. #define CFG_STATUS_IRQ_TERMINATION_OR_TAPER BIT(4)
  80. #define CFG_ADDRESS 0x0e
  81. /* Command registers */
  82. #define CMD_A 0x30
  83. #define CMD_A_CHG_ENABLED BIT(1)
  84. #define CMD_A_SUSPEND_ENABLED BIT(2)
  85. #define CMD_A_ALLOW_WRITE BIT(7)
  86. #define CMD_B 0x31
  87. #define CMD_C 0x33
  88. /* Interrupt Status registers */
  89. #define IRQSTAT_A 0x35
  90. #define IRQSTAT_C 0x37
  91. #define IRQSTAT_C_TERMINATION_STAT BIT(0)
  92. #define IRQSTAT_C_TERMINATION_IRQ BIT(1)
  93. #define IRQSTAT_C_TAPER_IRQ BIT(3)
  94. #define IRQSTAT_E 0x39
  95. #define IRQSTAT_E_USBIN_UV_STAT BIT(0)
  96. #define IRQSTAT_E_USBIN_UV_IRQ BIT(1)
  97. #define IRQSTAT_E_DCIN_UV_STAT BIT(4)
  98. #define IRQSTAT_E_DCIN_UV_IRQ BIT(5)
  99. #define IRQSTAT_F 0x3a
  100. /* Status registers */
  101. #define STAT_A 0x3b
  102. #define STAT_A_FLOAT_VOLTAGE_MASK 0x3f
  103. #define STAT_B 0x3c
  104. #define STAT_C 0x3d
  105. #define STAT_C_CHG_ENABLED BIT(0)
  106. #define STAT_C_CHG_MASK 0x06
  107. #define STAT_C_CHG_SHIFT 1
  108. #define STAT_C_CHARGER_ERROR BIT(6)
  109. #define STAT_E 0x3f
  110. /**
  111. * struct smb347_charger - smb347 charger instance
  112. * @lock: protects concurrent access to online variables
  113. * @client: pointer to i2c client
  114. * @mains: power_supply instance for AC/DC power
  115. * @usb: power_supply instance for USB power
  116. * @battery: power_supply instance for battery
  117. * @mains_online: is AC/DC input connected
  118. * @usb_online: is USB input connected
  119. * @charging_enabled: is charging enabled
  120. * @dentry: for debugfs
  121. * @pdata: pointer to platform data
  122. */
  123. struct smb347_charger {
  124. struct mutex lock;
  125. struct i2c_client *client;
  126. struct power_supply mains;
  127. struct power_supply usb;
  128. struct power_supply battery;
  129. bool mains_online;
  130. bool usb_online;
  131. bool charging_enabled;
  132. struct dentry *dentry;
  133. const struct smb347_charger_platform_data *pdata;
  134. };
  135. /* Fast charge current in uA */
  136. static const unsigned int fcc_tbl[] = {
  137. 700000,
  138. 900000,
  139. 1200000,
  140. 1500000,
  141. 1800000,
  142. 2000000,
  143. 2200000,
  144. 2500000,
  145. };
  146. /* Pre-charge current in uA */
  147. static const unsigned int pcc_tbl[] = {
  148. 100000,
  149. 150000,
  150. 200000,
  151. 250000,
  152. };
  153. /* Termination current in uA */
  154. static const unsigned int tc_tbl[] = {
  155. 37500,
  156. 50000,
  157. 100000,
  158. 150000,
  159. 200000,
  160. 250000,
  161. 500000,
  162. 600000,
  163. };
  164. /* Input current limit in uA */
  165. static const unsigned int icl_tbl[] = {
  166. 300000,
  167. 500000,
  168. 700000,
  169. 900000,
  170. 1200000,
  171. 1500000,
  172. 1800000,
  173. 2000000,
  174. 2200000,
  175. 2500000,
  176. };
  177. /* Charge current compensation in uA */
  178. static const unsigned int ccc_tbl[] = {
  179. 250000,
  180. 700000,
  181. 900000,
  182. 1200000,
  183. };
  184. /* Convert register value to current using lookup table */
  185. static int hw_to_current(const unsigned int *tbl, size_t size, unsigned int val)
  186. {
  187. if (val >= size)
  188. return -EINVAL;
  189. return tbl[val];
  190. }
  191. /* Convert current to register value using lookup table */
  192. static int current_to_hw(const unsigned int *tbl, size_t size, unsigned int val)
  193. {
  194. size_t i;
  195. for (i = 0; i < size; i++)
  196. if (val < tbl[i])
  197. break;
  198. return i > 0 ? i - 1 : -EINVAL;
  199. }
  200. static int smb347_read(struct smb347_charger *smb, u8 reg)
  201. {
  202. int ret;
  203. ret = i2c_smbus_read_byte_data(smb->client, reg);
  204. if (ret < 0)
  205. dev_warn(&smb->client->dev, "failed to read reg 0x%x: %d\n",
  206. reg, ret);
  207. return ret;
  208. }
  209. static int smb347_write(struct smb347_charger *smb, u8 reg, u8 val)
  210. {
  211. int ret;
  212. ret = i2c_smbus_write_byte_data(smb->client, reg, val);
  213. if (ret < 0)
  214. dev_warn(&smb->client->dev, "failed to write reg 0x%x: %d\n",
  215. reg, ret);
  216. return ret;
  217. }
  218. /**
  219. * smb347_update_status - updates the charging status
  220. * @smb: pointer to smb347 charger instance
  221. *
  222. * Function checks status of the charging and updates internal state
  223. * accordingly. Returns %0 if there is no change in status, %1 if the
  224. * status has changed and negative errno in case of failure.
  225. */
  226. static int smb347_update_status(struct smb347_charger *smb)
  227. {
  228. bool usb = false;
  229. bool dc = false;
  230. int ret;
  231. ret = smb347_read(smb, IRQSTAT_E);
  232. if (ret < 0)
  233. return ret;
  234. /*
  235. * Dc and usb are set depending on whether they are enabled in
  236. * platform data _and_ whether corresponding undervoltage is set.
  237. */
  238. if (smb->pdata->use_mains)
  239. dc = !(ret & IRQSTAT_E_DCIN_UV_STAT);
  240. if (smb->pdata->use_usb)
  241. usb = !(ret & IRQSTAT_E_USBIN_UV_STAT);
  242. mutex_lock(&smb->lock);
  243. ret = smb->mains_online != dc || smb->usb_online != usb;
  244. smb->mains_online = dc;
  245. smb->usb_online = usb;
  246. mutex_unlock(&smb->lock);
  247. return ret;
  248. }
  249. /*
  250. * smb347_is_online - returns whether input power source is connected
  251. * @smb: pointer to smb347 charger instance
  252. *
  253. * Returns %true if input power source is connected. Note that this is
  254. * dependent on what platform has configured for usable power sources. For
  255. * example if USB is disabled, this will return %false even if the USB
  256. * cable is connected.
  257. */
  258. static bool smb347_is_online(struct smb347_charger *smb)
  259. {
  260. bool ret;
  261. mutex_lock(&smb->lock);
  262. ret = smb->usb_online || smb->mains_online;
  263. mutex_unlock(&smb->lock);
  264. return ret;
  265. }
  266. /**
  267. * smb347_charging_status - returns status of charging
  268. * @smb: pointer to smb347 charger instance
  269. *
  270. * Function returns charging status. %0 means no charging is in progress,
  271. * %1 means pre-charging, %2 fast-charging and %3 taper-charging.
  272. */
  273. static int smb347_charging_status(struct smb347_charger *smb)
  274. {
  275. int ret;
  276. if (!smb347_is_online(smb))
  277. return 0;
  278. ret = smb347_read(smb, STAT_C);
  279. if (ret < 0)
  280. return 0;
  281. return (ret & STAT_C_CHG_MASK) >> STAT_C_CHG_SHIFT;
  282. }
  283. static int smb347_charging_set(struct smb347_charger *smb, bool enable)
  284. {
  285. int ret = 0;
  286. if (smb->pdata->enable_control != SMB347_CHG_ENABLE_SW) {
  287. dev_dbg(&smb->client->dev,
  288. "charging enable/disable in SW disabled\n");
  289. return 0;
  290. }
  291. mutex_lock(&smb->lock);
  292. if (smb->charging_enabled != enable) {
  293. ret = smb347_read(smb, CMD_A);
  294. if (ret < 0)
  295. goto out;
  296. smb->charging_enabled = enable;
  297. if (enable)
  298. ret |= CMD_A_CHG_ENABLED;
  299. else
  300. ret &= ~CMD_A_CHG_ENABLED;
  301. ret = smb347_write(smb, CMD_A, ret);
  302. }
  303. out:
  304. mutex_unlock(&smb->lock);
  305. return ret;
  306. }
  307. static inline int smb347_charging_enable(struct smb347_charger *smb)
  308. {
  309. return smb347_charging_set(smb, true);
  310. }
  311. static inline int smb347_charging_disable(struct smb347_charger *smb)
  312. {
  313. return smb347_charging_set(smb, false);
  314. }
  315. static int smb347_update_online(struct smb347_charger *smb)
  316. {
  317. int ret;
  318. /*
  319. * Depending on whether valid power source is connected or not, we
  320. * disable or enable the charging. We do it manually because it
  321. * depends on how the platform has configured the valid inputs.
  322. */
  323. if (smb347_is_online(smb)) {
  324. ret = smb347_charging_enable(smb);
  325. if (ret < 0)
  326. dev_err(&smb->client->dev,
  327. "failed to enable charging\n");
  328. } else {
  329. ret = smb347_charging_disable(smb);
  330. if (ret < 0)
  331. dev_err(&smb->client->dev,
  332. "failed to disable charging\n");
  333. }
  334. return ret;
  335. }
  336. static int smb347_set_charge_current(struct smb347_charger *smb)
  337. {
  338. int ret, val;
  339. ret = smb347_read(smb, CFG_CHARGE_CURRENT);
  340. if (ret < 0)
  341. return ret;
  342. if (smb->pdata->max_charge_current) {
  343. val = current_to_hw(fcc_tbl, ARRAY_SIZE(fcc_tbl),
  344. smb->pdata->max_charge_current);
  345. if (val < 0)
  346. return val;
  347. ret &= ~CFG_CHARGE_CURRENT_FCC_MASK;
  348. ret |= val << CFG_CHARGE_CURRENT_FCC_SHIFT;
  349. }
  350. if (smb->pdata->pre_charge_current) {
  351. val = current_to_hw(pcc_tbl, ARRAY_SIZE(pcc_tbl),
  352. smb->pdata->pre_charge_current);
  353. if (val < 0)
  354. return val;
  355. ret &= ~CFG_CHARGE_CURRENT_PCC_MASK;
  356. ret |= val << CFG_CHARGE_CURRENT_PCC_SHIFT;
  357. }
  358. if (smb->pdata->termination_current) {
  359. val = current_to_hw(tc_tbl, ARRAY_SIZE(tc_tbl),
  360. smb->pdata->termination_current);
  361. if (val < 0)
  362. return val;
  363. ret &= ~CFG_CHARGE_CURRENT_TC_MASK;
  364. ret |= val;
  365. }
  366. return smb347_write(smb, CFG_CHARGE_CURRENT, ret);
  367. }
  368. static int smb347_set_current_limits(struct smb347_charger *smb)
  369. {
  370. int ret, val;
  371. ret = smb347_read(smb, CFG_CURRENT_LIMIT);
  372. if (ret < 0)
  373. return ret;
  374. if (smb->pdata->mains_current_limit) {
  375. val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
  376. smb->pdata->mains_current_limit);
  377. if (val < 0)
  378. return val;
  379. ret &= ~CFG_CURRENT_LIMIT_DC_MASK;
  380. ret |= val << CFG_CURRENT_LIMIT_DC_SHIFT;
  381. }
  382. if (smb->pdata->usb_hc_current_limit) {
  383. val = current_to_hw(icl_tbl, ARRAY_SIZE(icl_tbl),
  384. smb->pdata->usb_hc_current_limit);
  385. if (val < 0)
  386. return val;
  387. ret &= ~CFG_CURRENT_LIMIT_USB_MASK;
  388. ret |= val;
  389. }
  390. return smb347_write(smb, CFG_CURRENT_LIMIT, ret);
  391. }
  392. static int smb347_set_voltage_limits(struct smb347_charger *smb)
  393. {
  394. int ret, val;
  395. ret = smb347_read(smb, CFG_FLOAT_VOLTAGE);
  396. if (ret < 0)
  397. return ret;
  398. if (smb->pdata->pre_to_fast_voltage) {
  399. val = smb->pdata->pre_to_fast_voltage;
  400. /* uV */
  401. val = clamp_val(val, 2400000, 3000000) - 2400000;
  402. val /= 200000;
  403. ret &= ~CFG_FLOAT_VOLTAGE_THRESHOLD_MASK;
  404. ret |= val << CFG_FLOAT_VOLTAGE_THRESHOLD_SHIFT;
  405. }
  406. if (smb->pdata->max_charge_voltage) {
  407. val = smb->pdata->max_charge_voltage;
  408. /* uV */
  409. val = clamp_val(val, 3500000, 4500000) - 3500000;
  410. val /= 20000;
  411. ret |= val;
  412. }
  413. return smb347_write(smb, CFG_FLOAT_VOLTAGE, ret);
  414. }
  415. static int smb347_set_temp_limits(struct smb347_charger *smb)
  416. {
  417. bool enable_therm_monitor = false;
  418. int ret, val;
  419. if (smb->pdata->chip_temp_threshold) {
  420. val = smb->pdata->chip_temp_threshold;
  421. /* degree C */
  422. val = clamp_val(val, 100, 130) - 100;
  423. val /= 10;
  424. ret = smb347_read(smb, CFG_OTG);
  425. if (ret < 0)
  426. return ret;
  427. ret &= ~CFG_OTG_TEMP_THRESHOLD_MASK;
  428. ret |= val << CFG_OTG_TEMP_THRESHOLD_SHIFT;
  429. ret = smb347_write(smb, CFG_OTG, ret);
  430. if (ret < 0)
  431. return ret;
  432. }
  433. ret = smb347_read(smb, CFG_TEMP_LIMIT);
  434. if (ret < 0)
  435. return ret;
  436. if (smb->pdata->soft_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) {
  437. val = smb->pdata->soft_cold_temp_limit;
  438. val = clamp_val(val, 0, 15);
  439. val /= 5;
  440. /* this goes from higher to lower so invert the value */
  441. val = ~val & 0x3;
  442. ret &= ~CFG_TEMP_LIMIT_SOFT_COLD_MASK;
  443. ret |= val << CFG_TEMP_LIMIT_SOFT_COLD_SHIFT;
  444. enable_therm_monitor = true;
  445. }
  446. if (smb->pdata->soft_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) {
  447. val = smb->pdata->soft_hot_temp_limit;
  448. val = clamp_val(val, 40, 55) - 40;
  449. val /= 5;
  450. ret &= ~CFG_TEMP_LIMIT_SOFT_HOT_MASK;
  451. ret |= val << CFG_TEMP_LIMIT_SOFT_HOT_SHIFT;
  452. enable_therm_monitor = true;
  453. }
  454. if (smb->pdata->hard_cold_temp_limit != SMB347_TEMP_USE_DEFAULT) {
  455. val = smb->pdata->hard_cold_temp_limit;
  456. val = clamp_val(val, -5, 10) + 5;
  457. val /= 5;
  458. /* this goes from higher to lower so invert the value */
  459. val = ~val & 0x3;
  460. ret &= ~CFG_TEMP_LIMIT_HARD_COLD_MASK;
  461. ret |= val << CFG_TEMP_LIMIT_HARD_COLD_SHIFT;
  462. enable_therm_monitor = true;
  463. }
  464. if (smb->pdata->hard_hot_temp_limit != SMB347_TEMP_USE_DEFAULT) {
  465. val = smb->pdata->hard_hot_temp_limit;
  466. val = clamp_val(val, 50, 65) - 50;
  467. val /= 5;
  468. ret &= ~CFG_TEMP_LIMIT_HARD_HOT_MASK;
  469. ret |= val << CFG_TEMP_LIMIT_HARD_HOT_SHIFT;
  470. enable_therm_monitor = true;
  471. }
  472. ret = smb347_write(smb, CFG_TEMP_LIMIT, ret);
  473. if (ret < 0)
  474. return ret;
  475. /*
  476. * If any of the temperature limits are set, we also enable the
  477. * thermistor monitoring.
  478. *
  479. * When soft limits are hit, the device will start to compensate
  480. * current and/or voltage depending on the configuration.
  481. *
  482. * When hard limit is hit, the device will suspend charging
  483. * depending on the configuration.
  484. */
  485. if (enable_therm_monitor) {
  486. ret = smb347_read(smb, CFG_THERM);
  487. if (ret < 0)
  488. return ret;
  489. ret &= ~CFG_THERM_MONITOR_DISABLED;
  490. ret = smb347_write(smb, CFG_THERM, ret);
  491. if (ret < 0)
  492. return ret;
  493. }
  494. if (smb->pdata->suspend_on_hard_temp_limit) {
  495. ret = smb347_read(smb, CFG_SYSOK);
  496. if (ret < 0)
  497. return ret;
  498. ret &= ~CFG_SYSOK_SUSPEND_HARD_LIMIT_DISABLED;
  499. ret = smb347_write(smb, CFG_SYSOK, ret);
  500. if (ret < 0)
  501. return ret;
  502. }
  503. if (smb->pdata->soft_temp_limit_compensation !=
  504. SMB347_SOFT_TEMP_COMPENSATE_DEFAULT) {
  505. val = smb->pdata->soft_temp_limit_compensation & 0x3;
  506. ret = smb347_read(smb, CFG_THERM);
  507. if (ret < 0)
  508. return ret;
  509. ret &= ~CFG_THERM_SOFT_HOT_COMPENSATION_MASK;
  510. ret |= val << CFG_THERM_SOFT_HOT_COMPENSATION_SHIFT;
  511. ret &= ~CFG_THERM_SOFT_COLD_COMPENSATION_MASK;
  512. ret |= val << CFG_THERM_SOFT_COLD_COMPENSATION_SHIFT;
  513. ret = smb347_write(smb, CFG_THERM, ret);
  514. if (ret < 0)
  515. return ret;
  516. }
  517. if (smb->pdata->charge_current_compensation) {
  518. val = current_to_hw(ccc_tbl, ARRAY_SIZE(ccc_tbl),
  519. smb->pdata->charge_current_compensation);
  520. if (val < 0)
  521. return val;
  522. ret = smb347_read(smb, CFG_OTG);
  523. if (ret < 0)
  524. return ret;
  525. ret &= ~CFG_OTG_CC_COMPENSATION_MASK;
  526. ret |= (val & 0x3) << CFG_OTG_CC_COMPENSATION_SHIFT;
  527. ret = smb347_write(smb, CFG_OTG, ret);
  528. if (ret < 0)
  529. return ret;
  530. }
  531. return ret;
  532. }
  533. /*
  534. * smb347_set_writable - enables/disables writing to non-volatile registers
  535. * @smb: pointer to smb347 charger instance
  536. *
  537. * You can enable/disable writing to the non-volatile configuration
  538. * registers by calling this function.
  539. *
  540. * Returns %0 on success and negative errno in case of failure.
  541. */
  542. static int smb347_set_writable(struct smb347_charger *smb, bool writable)
  543. {
  544. int ret;
  545. ret = smb347_read(smb, CMD_A);
  546. if (ret < 0)
  547. return ret;
  548. if (writable)
  549. ret |= CMD_A_ALLOW_WRITE;
  550. else
  551. ret &= ~CMD_A_ALLOW_WRITE;
  552. return smb347_write(smb, CMD_A, ret);
  553. }
  554. static int smb347_hw_init(struct smb347_charger *smb)
  555. {
  556. int ret;
  557. ret = smb347_set_writable(smb, true);
  558. if (ret < 0)
  559. return ret;
  560. /*
  561. * Program the platform specific configuration values to the device
  562. * first.
  563. */
  564. ret = smb347_set_charge_current(smb);
  565. if (ret < 0)
  566. goto fail;
  567. ret = smb347_set_current_limits(smb);
  568. if (ret < 0)
  569. goto fail;
  570. ret = smb347_set_voltage_limits(smb);
  571. if (ret < 0)
  572. goto fail;
  573. ret = smb347_set_temp_limits(smb);
  574. if (ret < 0)
  575. goto fail;
  576. /* If USB charging is disabled we put the USB in suspend mode */
  577. if (!smb->pdata->use_usb) {
  578. ret = smb347_read(smb, CMD_A);
  579. if (ret < 0)
  580. goto fail;
  581. ret |= CMD_A_SUSPEND_ENABLED;
  582. ret = smb347_write(smb, CMD_A, ret);
  583. if (ret < 0)
  584. goto fail;
  585. }
  586. ret = smb347_read(smb, CFG_OTHER);
  587. if (ret < 0)
  588. goto fail;
  589. /*
  590. * If configured by platform data, we enable hardware Auto-OTG
  591. * support for driving VBUS. Otherwise we disable it.
  592. */
  593. ret &= ~CFG_OTHER_RID_MASK;
  594. if (smb->pdata->use_usb_otg)
  595. ret |= CFG_OTHER_RID_ENABLED_AUTO_OTG;
  596. ret = smb347_write(smb, CFG_OTHER, ret);
  597. if (ret < 0)
  598. goto fail;
  599. ret = smb347_read(smb, CFG_PIN);
  600. if (ret < 0)
  601. goto fail;
  602. /*
  603. * Make the charging functionality controllable by a write to the
  604. * command register unless pin control is specified in the platform
  605. * data.
  606. */
  607. ret &= ~CFG_PIN_EN_CTRL_MASK;
  608. switch (smb->pdata->enable_control) {
  609. case SMB347_CHG_ENABLE_SW:
  610. /* Do nothing, 0 means i2c control */
  611. break;
  612. case SMB347_CHG_ENABLE_PIN_ACTIVE_LOW:
  613. ret |= CFG_PIN_EN_CTRL_ACTIVE_LOW;
  614. break;
  615. case SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH:
  616. ret |= CFG_PIN_EN_CTRL_ACTIVE_HIGH;
  617. break;
  618. }
  619. /* Disable Automatic Power Source Detection (APSD) interrupt. */
  620. ret &= ~CFG_PIN_EN_APSD_IRQ;
  621. ret = smb347_write(smb, CFG_PIN, ret);
  622. if (ret < 0)
  623. goto fail;
  624. ret = smb347_update_status(smb);
  625. if (ret < 0)
  626. goto fail;
  627. ret = smb347_update_online(smb);
  628. fail:
  629. smb347_set_writable(smb, false);
  630. return ret;
  631. }
  632. static irqreturn_t smb347_interrupt(int irq, void *data)
  633. {
  634. struct smb347_charger *smb = data;
  635. int stat_c, irqstat_e, irqstat_c;
  636. irqreturn_t ret = IRQ_NONE;
  637. stat_c = smb347_read(smb, STAT_C);
  638. if (stat_c < 0) {
  639. dev_warn(&smb->client->dev, "reading STAT_C failed\n");
  640. return IRQ_NONE;
  641. }
  642. irqstat_c = smb347_read(smb, IRQSTAT_C);
  643. if (irqstat_c < 0) {
  644. dev_warn(&smb->client->dev, "reading IRQSTAT_C failed\n");
  645. return IRQ_NONE;
  646. }
  647. irqstat_e = smb347_read(smb, IRQSTAT_E);
  648. if (irqstat_e < 0) {
  649. dev_warn(&smb->client->dev, "reading IRQSTAT_E failed\n");
  650. return IRQ_NONE;
  651. }
  652. /*
  653. * If we get charger error we report the error back to user and
  654. * disable charging.
  655. */
  656. if (stat_c & STAT_C_CHARGER_ERROR) {
  657. dev_err(&smb->client->dev,
  658. "error in charger, disabling charging\n");
  659. smb347_charging_disable(smb);
  660. power_supply_changed(&smb->battery);
  661. ret = IRQ_HANDLED;
  662. }
  663. /*
  664. * If we reached the termination current the battery is charged and
  665. * we can update the status now. Charging is automatically
  666. * disabled by the hardware.
  667. */
  668. if (irqstat_c & (IRQSTAT_C_TERMINATION_IRQ | IRQSTAT_C_TAPER_IRQ)) {
  669. if (irqstat_c & IRQSTAT_C_TERMINATION_STAT)
  670. power_supply_changed(&smb->battery);
  671. ret = IRQ_HANDLED;
  672. }
  673. /*
  674. * If we got an under voltage interrupt it means that AC/USB input
  675. * was connected or disconnected.
  676. */
  677. if (irqstat_e & (IRQSTAT_E_USBIN_UV_IRQ | IRQSTAT_E_DCIN_UV_IRQ)) {
  678. if (smb347_update_status(smb) > 0) {
  679. smb347_update_online(smb);
  680. power_supply_changed(&smb->mains);
  681. power_supply_changed(&smb->usb);
  682. }
  683. ret = IRQ_HANDLED;
  684. }
  685. return ret;
  686. }
  687. static int smb347_irq_set(struct smb347_charger *smb, bool enable)
  688. {
  689. int ret;
  690. ret = smb347_set_writable(smb, true);
  691. if (ret < 0)
  692. return ret;
  693. /*
  694. * Enable/disable interrupts for:
  695. * - under voltage
  696. * - termination current reached
  697. * - charger error
  698. */
  699. if (enable) {
  700. ret = smb347_write(smb, CFG_FAULT_IRQ, CFG_FAULT_IRQ_DCIN_UV);
  701. if (ret < 0)
  702. goto fail;
  703. ret = smb347_write(smb, CFG_STATUS_IRQ,
  704. CFG_STATUS_IRQ_TERMINATION_OR_TAPER);
  705. if (ret < 0)
  706. goto fail;
  707. ret = smb347_read(smb, CFG_PIN);
  708. if (ret < 0)
  709. goto fail;
  710. ret |= CFG_PIN_EN_CHARGER_ERROR;
  711. ret = smb347_write(smb, CFG_PIN, ret);
  712. } else {
  713. ret = smb347_write(smb, CFG_FAULT_IRQ, 0);
  714. if (ret < 0)
  715. goto fail;
  716. ret = smb347_write(smb, CFG_STATUS_IRQ, 0);
  717. if (ret < 0)
  718. goto fail;
  719. ret = smb347_read(smb, CFG_PIN);
  720. if (ret < 0)
  721. goto fail;
  722. ret &= ~CFG_PIN_EN_CHARGER_ERROR;
  723. ret = smb347_write(smb, CFG_PIN, ret);
  724. }
  725. fail:
  726. smb347_set_writable(smb, false);
  727. return ret;
  728. }
  729. static inline int smb347_irq_enable(struct smb347_charger *smb)
  730. {
  731. return smb347_irq_set(smb, true);
  732. }
  733. static inline int smb347_irq_disable(struct smb347_charger *smb)
  734. {
  735. return smb347_irq_set(smb, false);
  736. }
  737. static int smb347_irq_init(struct smb347_charger *smb)
  738. {
  739. const struct smb347_charger_platform_data *pdata = smb->pdata;
  740. int ret, irq = gpio_to_irq(pdata->irq_gpio);
  741. ret = gpio_request_one(pdata->irq_gpio, GPIOF_IN, smb->client->name);
  742. if (ret < 0)
  743. goto fail;
  744. ret = request_threaded_irq(irq, NULL, smb347_interrupt,
  745. IRQF_TRIGGER_FALLING, smb->client->name,
  746. smb);
  747. if (ret < 0)
  748. goto fail_gpio;
  749. ret = smb347_set_writable(smb, true);
  750. if (ret < 0)
  751. goto fail_irq;
  752. /*
  753. * Configure the STAT output to be suitable for interrupts: disable
  754. * all other output (except interrupts) and make it active low.
  755. */
  756. ret = smb347_read(smb, CFG_STAT);
  757. if (ret < 0)
  758. goto fail_readonly;
  759. ret &= ~CFG_STAT_ACTIVE_HIGH;
  760. ret |= CFG_STAT_DISABLED;
  761. ret = smb347_write(smb, CFG_STAT, ret);
  762. if (ret < 0)
  763. goto fail_readonly;
  764. ret = smb347_irq_enable(smb);
  765. if (ret < 0)
  766. goto fail_readonly;
  767. smb347_set_writable(smb, false);
  768. smb->client->irq = irq;
  769. return 0;
  770. fail_readonly:
  771. smb347_set_writable(smb, false);
  772. fail_irq:
  773. free_irq(irq, smb);
  774. fail_gpio:
  775. gpio_free(pdata->irq_gpio);
  776. fail:
  777. smb->client->irq = 0;
  778. return ret;
  779. }
  780. static int smb347_mains_get_property(struct power_supply *psy,
  781. enum power_supply_property prop,
  782. union power_supply_propval *val)
  783. {
  784. struct smb347_charger *smb =
  785. container_of(psy, struct smb347_charger, mains);
  786. if (prop == POWER_SUPPLY_PROP_ONLINE) {
  787. val->intval = smb->mains_online;
  788. return 0;
  789. }
  790. return -EINVAL;
  791. }
  792. static enum power_supply_property smb347_mains_properties[] = {
  793. POWER_SUPPLY_PROP_ONLINE,
  794. };
  795. static int smb347_usb_get_property(struct power_supply *psy,
  796. enum power_supply_property prop,
  797. union power_supply_propval *val)
  798. {
  799. struct smb347_charger *smb =
  800. container_of(psy, struct smb347_charger, usb);
  801. if (prop == POWER_SUPPLY_PROP_ONLINE) {
  802. val->intval = smb->usb_online;
  803. return 0;
  804. }
  805. return -EINVAL;
  806. }
  807. static enum power_supply_property smb347_usb_properties[] = {
  808. POWER_SUPPLY_PROP_ONLINE,
  809. };
  810. static int smb347_battery_get_property(struct power_supply *psy,
  811. enum power_supply_property prop,
  812. union power_supply_propval *val)
  813. {
  814. struct smb347_charger *smb =
  815. container_of(psy, struct smb347_charger, battery);
  816. const struct smb347_charger_platform_data *pdata = smb->pdata;
  817. int ret;
  818. ret = smb347_update_status(smb);
  819. if (ret < 0)
  820. return ret;
  821. switch (prop) {
  822. case POWER_SUPPLY_PROP_STATUS:
  823. if (!smb347_is_online(smb)) {
  824. val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  825. break;
  826. }
  827. if (smb347_charging_status(smb))
  828. val->intval = POWER_SUPPLY_STATUS_CHARGING;
  829. else
  830. val->intval = POWER_SUPPLY_STATUS_FULL;
  831. break;
  832. case POWER_SUPPLY_PROP_CHARGE_TYPE:
  833. if (!smb347_is_online(smb))
  834. return -ENODATA;
  835. /*
  836. * We handle trickle and pre-charging the same, and taper
  837. * and none the same.
  838. */
  839. switch (smb347_charging_status(smb)) {
  840. case 1:
  841. val->intval = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
  842. break;
  843. case 2:
  844. val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
  845. break;
  846. default:
  847. val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
  848. break;
  849. }
  850. break;
  851. case POWER_SUPPLY_PROP_TECHNOLOGY:
  852. val->intval = pdata->battery_info.technology;
  853. break;
  854. case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
  855. val->intval = pdata->battery_info.voltage_min_design;
  856. break;
  857. case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
  858. val->intval = pdata->battery_info.voltage_max_design;
  859. break;
  860. case POWER_SUPPLY_PROP_VOLTAGE_NOW:
  861. if (!smb347_is_online(smb))
  862. return -ENODATA;
  863. ret = smb347_read(smb, STAT_A);
  864. if (ret < 0)
  865. return ret;
  866. ret &= STAT_A_FLOAT_VOLTAGE_MASK;
  867. if (ret > 0x3d)
  868. ret = 0x3d;
  869. val->intval = 3500000 + ret * 20000;
  870. break;
  871. case POWER_SUPPLY_PROP_CURRENT_NOW:
  872. if (!smb347_is_online(smb))
  873. return -ENODATA;
  874. ret = smb347_read(smb, STAT_B);
  875. if (ret < 0)
  876. return ret;
  877. /*
  878. * The current value is composition of FCC and PCC values
  879. * and we can detect which table to use from bit 5.
  880. */
  881. if (ret & 0x20) {
  882. val->intval = hw_to_current(fcc_tbl,
  883. ARRAY_SIZE(fcc_tbl),
  884. ret & 7);
  885. } else {
  886. ret >>= 3;
  887. val->intval = hw_to_current(pcc_tbl,
  888. ARRAY_SIZE(pcc_tbl),
  889. ret & 7);
  890. }
  891. break;
  892. case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
  893. val->intval = pdata->battery_info.charge_full_design;
  894. break;
  895. case POWER_SUPPLY_PROP_MODEL_NAME:
  896. val->strval = pdata->battery_info.name;
  897. break;
  898. default:
  899. return -EINVAL;
  900. }
  901. return 0;
  902. }
  903. static enum power_supply_property smb347_battery_properties[] = {
  904. POWER_SUPPLY_PROP_STATUS,
  905. POWER_SUPPLY_PROP_CHARGE_TYPE,
  906. POWER_SUPPLY_PROP_TECHNOLOGY,
  907. POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
  908. POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
  909. POWER_SUPPLY_PROP_VOLTAGE_NOW,
  910. POWER_SUPPLY_PROP_CURRENT_NOW,
  911. POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
  912. POWER_SUPPLY_PROP_MODEL_NAME,
  913. };
  914. static int smb347_debugfs_show(struct seq_file *s, void *data)
  915. {
  916. struct smb347_charger *smb = s->private;
  917. int ret;
  918. u8 reg;
  919. seq_printf(s, "Control registers:\n");
  920. seq_printf(s, "==================\n");
  921. for (reg = CFG_CHARGE_CURRENT; reg <= CFG_ADDRESS; reg++) {
  922. ret = smb347_read(smb, reg);
  923. seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret);
  924. }
  925. seq_printf(s, "\n");
  926. seq_printf(s, "Command registers:\n");
  927. seq_printf(s, "==================\n");
  928. ret = smb347_read(smb, CMD_A);
  929. seq_printf(s, "0x%02x:\t0x%02x\n", CMD_A, ret);
  930. ret = smb347_read(smb, CMD_B);
  931. seq_printf(s, "0x%02x:\t0x%02x\n", CMD_B, ret);
  932. ret = smb347_read(smb, CMD_C);
  933. seq_printf(s, "0x%02x:\t0x%02x\n", CMD_C, ret);
  934. seq_printf(s, "\n");
  935. seq_printf(s, "Interrupt status registers:\n");
  936. seq_printf(s, "===========================\n");
  937. for (reg = IRQSTAT_A; reg <= IRQSTAT_F; reg++) {
  938. ret = smb347_read(smb, reg);
  939. seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret);
  940. }
  941. seq_printf(s, "\n");
  942. seq_printf(s, "Status registers:\n");
  943. seq_printf(s, "=================\n");
  944. for (reg = STAT_A; reg <= STAT_E; reg++) {
  945. ret = smb347_read(smb, reg);
  946. seq_printf(s, "0x%02x:\t0x%02x\n", reg, ret);
  947. }
  948. return 0;
  949. }
  950. static int smb347_debugfs_open(struct inode *inode, struct file *file)
  951. {
  952. return single_open(file, smb347_debugfs_show, inode->i_private);
  953. }
  954. static const struct file_operations smb347_debugfs_fops = {
  955. .open = smb347_debugfs_open,
  956. .read = seq_read,
  957. .llseek = seq_lseek,
  958. .release = single_release,
  959. };
  960. static int smb347_probe(struct i2c_client *client,
  961. const struct i2c_device_id *id)
  962. {
  963. static char *battery[] = { "smb347-battery" };
  964. const struct smb347_charger_platform_data *pdata;
  965. struct device *dev = &client->dev;
  966. struct smb347_charger *smb;
  967. int ret;
  968. pdata = dev->platform_data;
  969. if (!pdata)
  970. return -EINVAL;
  971. if (!pdata->use_mains && !pdata->use_usb)
  972. return -EINVAL;
  973. smb = devm_kzalloc(dev, sizeof(*smb), GFP_KERNEL);
  974. if (!smb)
  975. return -ENOMEM;
  976. i2c_set_clientdata(client, smb);
  977. mutex_init(&smb->lock);
  978. smb->client = client;
  979. smb->pdata = pdata;
  980. ret = smb347_hw_init(smb);
  981. if (ret < 0)
  982. return ret;
  983. smb->mains.name = "smb347-mains";
  984. smb->mains.type = POWER_SUPPLY_TYPE_MAINS;
  985. smb->mains.get_property = smb347_mains_get_property;
  986. smb->mains.properties = smb347_mains_properties;
  987. smb->mains.num_properties = ARRAY_SIZE(smb347_mains_properties);
  988. smb->mains.supplied_to = battery;
  989. smb->mains.num_supplicants = ARRAY_SIZE(battery);
  990. smb->usb.name = "smb347-usb";
  991. smb->usb.type = POWER_SUPPLY_TYPE_USB;
  992. smb->usb.get_property = smb347_usb_get_property;
  993. smb->usb.properties = smb347_usb_properties;
  994. smb->usb.num_properties = ARRAY_SIZE(smb347_usb_properties);
  995. smb->usb.supplied_to = battery;
  996. smb->usb.num_supplicants = ARRAY_SIZE(battery);
  997. smb->battery.name = "smb347-battery";
  998. smb->battery.type = POWER_SUPPLY_TYPE_BATTERY;
  999. smb->battery.get_property = smb347_battery_get_property;
  1000. smb->battery.properties = smb347_battery_properties;
  1001. smb->battery.num_properties = ARRAY_SIZE(smb347_battery_properties);
  1002. ret = power_supply_register(dev, &smb->mains);
  1003. if (ret < 0)
  1004. return ret;
  1005. ret = power_supply_register(dev, &smb->usb);
  1006. if (ret < 0) {
  1007. power_supply_unregister(&smb->mains);
  1008. return ret;
  1009. }
  1010. ret = power_supply_register(dev, &smb->battery);
  1011. if (ret < 0) {
  1012. power_supply_unregister(&smb->usb);
  1013. power_supply_unregister(&smb->mains);
  1014. return ret;
  1015. }
  1016. /*
  1017. * Interrupt pin is optional. If it is connected, we setup the
  1018. * interrupt support here.
  1019. */
  1020. if (pdata->irq_gpio >= 0) {
  1021. ret = smb347_irq_init(smb);
  1022. if (ret < 0) {
  1023. dev_warn(dev, "failed to initialize IRQ: %d\n", ret);
  1024. dev_warn(dev, "disabling IRQ support\n");
  1025. }
  1026. }
  1027. smb->dentry = debugfs_create_file("smb347-regs", S_IRUSR, NULL, smb,
  1028. &smb347_debugfs_fops);
  1029. return 0;
  1030. }
  1031. static int smb347_remove(struct i2c_client *client)
  1032. {
  1033. struct smb347_charger *smb = i2c_get_clientdata(client);
  1034. if (!IS_ERR_OR_NULL(smb->dentry))
  1035. debugfs_remove(smb->dentry);
  1036. if (client->irq) {
  1037. smb347_irq_disable(smb);
  1038. free_irq(client->irq, smb);
  1039. gpio_free(smb->pdata->irq_gpio);
  1040. }
  1041. power_supply_unregister(&smb->battery);
  1042. power_supply_unregister(&smb->usb);
  1043. power_supply_unregister(&smb->mains);
  1044. return 0;
  1045. }
  1046. static const struct i2c_device_id smb347_id[] = {
  1047. { "smb347", 0 },
  1048. { }
  1049. };
  1050. MODULE_DEVICE_TABLE(i2c, smb347_id);
  1051. static struct i2c_driver smb347_driver = {
  1052. .driver = {
  1053. .name = "smb347",
  1054. },
  1055. .probe = smb347_probe,
  1056. .remove = __devexit_p(smb347_remove),
  1057. .id_table = smb347_id,
  1058. };
  1059. static int __init smb347_init(void)
  1060. {
  1061. return i2c_add_driver(&smb347_driver);
  1062. }
  1063. module_init(smb347_init);
  1064. static void __exit smb347_exit(void)
  1065. {
  1066. i2c_del_driver(&smb347_driver);
  1067. }
  1068. module_exit(smb347_exit);
  1069. MODULE_AUTHOR("Bruce E. Robertson <bruce.e.robertson@intel.com>");
  1070. MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
  1071. MODULE_DESCRIPTION("SMB347 battery charger driver");
  1072. MODULE_LICENSE("GPL");
  1073. MODULE_ALIAS("i2c:smb347");