mt6370-charger.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2022 Richtek Technology Corp.
  4. *
  5. * Author: ChiaEn Wu <[email protected]>
  6. */
  7. #include <linux/bitfield.h>
  8. #include <linux/bits.h>
  9. #include <linux/devm-helpers.h>
  10. #include <linux/gpio/consumer.h>
  11. #include <linux/iio/consumer.h>
  12. #include <linux/init.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/kernel.h>
  15. #include <linux/linear_range.h>
  16. #include <linux/module.h>
  17. #include <linux/of.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/power_supply.h>
  20. #include <linux/regmap.h>
  21. #include <linux/regulator/driver.h>
  22. #include <linux/workqueue.h>
  23. #define MT6370_REG_CHG_CTRL1 0x111
  24. #define MT6370_REG_CHG_CTRL2 0x112
  25. #define MT6370_REG_CHG_CTRL3 0x113
  26. #define MT6370_REG_CHG_CTRL4 0x114
  27. #define MT6370_REG_CHG_CTRL5 0x115
  28. #define MT6370_REG_CHG_CTRL6 0x116
  29. #define MT6370_REG_CHG_CTRL7 0x117
  30. #define MT6370_REG_CHG_CTRL8 0x118
  31. #define MT6370_REG_CHG_CTRL9 0x119
  32. #define MT6370_REG_CHG_CTRL10 0x11A
  33. #define MT6370_REG_DEVICE_TYPE 0x122
  34. #define MT6370_REG_USB_STATUS1 0x127
  35. #define MT6370_REG_CHG_STAT 0x14A
  36. #define MT6370_REG_FLED_EN 0x17E
  37. #define MT6370_REG_CHG_STAT1 0X1D0
  38. #define MT6370_REG_OVPCTRL_STAT 0x1D8
  39. #define MT6370_VOBST_MASK GENMASK(7, 2)
  40. #define MT6370_OTG_PIN_EN_MASK BIT(1)
  41. #define MT6370_OPA_MODE_MASK BIT(0)
  42. #define MT6370_OTG_OC_MASK GENMASK(2, 0)
  43. #define MT6370_MIVR_IBUS_TH_100_mA 100000
  44. #define MT6370_ADC_CHAN_IBUS 5
  45. #define MT6370_ADC_CHAN_MAX 9
  46. enum mt6370_chg_reg_field {
  47. /* MT6370_REG_CHG_CTRL2 */
  48. F_IINLMTSEL, F_CFO_EN, F_CHG_EN,
  49. /* MT6370_REG_CHG_CTRL3 */
  50. F_IAICR, F_AICR_EN, F_ILIM_EN,
  51. /* MT6370_REG_CHG_CTRL4 */
  52. F_VOREG,
  53. /* MT6370_REG_CHG_CTRL6 */
  54. F_VMIVR,
  55. /* MT6370_REG_CHG_CTRL7 */
  56. F_ICHG,
  57. /* MT6370_REG_CHG_CTRL8 */
  58. F_IPREC,
  59. /* MT6370_REG_CHG_CTRL9 */
  60. F_IEOC,
  61. /* MT6370_REG_DEVICE_TYPE */
  62. F_USBCHGEN,
  63. /* MT6370_REG_USB_STATUS1 */
  64. F_USB_STAT, F_CHGDET,
  65. /* MT6370_REG_CHG_STAT */
  66. F_CHG_STAT, F_BOOST_STAT, F_VBAT_LVL,
  67. /* MT6370_REG_FLED_EN */
  68. F_FL_STROBE,
  69. /* MT6370_REG_CHG_STAT1 */
  70. F_CHG_MIVR_STAT,
  71. /* MT6370_REG_OVPCTRL_STAT */
  72. F_UVP_D_STAT,
  73. F_MAX
  74. };
  75. enum mt6370_irq {
  76. MT6370_IRQ_ATTACH_I = 0,
  77. MT6370_IRQ_UVP_D_EVT,
  78. MT6370_IRQ_MIVR,
  79. MT6370_IRQ_MAX
  80. };
  81. struct mt6370_priv {
  82. struct device *dev;
  83. struct iio_channel *iio_adcs;
  84. struct mutex attach_lock;
  85. struct power_supply *psy;
  86. struct regmap *regmap;
  87. struct regmap_field *rmap_fields[F_MAX];
  88. struct regulator_dev *rdev;
  89. struct workqueue_struct *wq;
  90. struct work_struct bc12_work;
  91. struct delayed_work mivr_dwork;
  92. unsigned int irq_nums[MT6370_IRQ_MAX];
  93. int attach;
  94. int psy_usb_type;
  95. bool pwr_rdy;
  96. };
  97. enum mt6370_usb_status {
  98. MT6370_USB_STAT_NO_VBUS = 0,
  99. MT6370_USB_STAT_VBUS_FLOW_IS_UNDER_GOING,
  100. MT6370_USB_STAT_SDP,
  101. MT6370_USB_STAT_SDP_NSTD,
  102. MT6370_USB_STAT_DCP,
  103. MT6370_USB_STAT_CDP,
  104. MT6370_USB_STAT_MAX
  105. };
  106. struct mt6370_chg_field {
  107. const char *name;
  108. const struct linear_range *range;
  109. struct reg_field field;
  110. };
  111. enum {
  112. MT6370_RANGE_F_IAICR = 0,
  113. MT6370_RANGE_F_VOREG,
  114. MT6370_RANGE_F_VMIVR,
  115. MT6370_RANGE_F_ICHG,
  116. MT6370_RANGE_F_IPREC,
  117. MT6370_RANGE_F_IEOC,
  118. MT6370_RANGE_F_MAX
  119. };
  120. static const struct linear_range mt6370_chg_ranges[MT6370_RANGE_F_MAX] = {
  121. LINEAR_RANGE_IDX(MT6370_RANGE_F_IAICR, 100000, 0x0, 0x3F, 50000),
  122. LINEAR_RANGE_IDX(MT6370_RANGE_F_VOREG, 3900000, 0x0, 0x51, 10000),
  123. LINEAR_RANGE_IDX(MT6370_RANGE_F_VMIVR, 3900000, 0x0, 0x5F, 100000),
  124. LINEAR_RANGE_IDX(MT6370_RANGE_F_ICHG, 900000, 0x08, 0x31, 100000),
  125. LINEAR_RANGE_IDX(MT6370_RANGE_F_IPREC, 100000, 0x0, 0x0F, 50000),
  126. LINEAR_RANGE_IDX(MT6370_RANGE_F_IEOC, 100000, 0x0, 0x0F, 50000),
  127. };
  128. #define MT6370_CHG_FIELD(_fd, _reg, _lsb, _msb) \
  129. [_fd] = { \
  130. .name = #_fd, \
  131. .range = NULL, \
  132. .field = REG_FIELD(_reg, _lsb, _msb), \
  133. }
  134. #define MT6370_CHG_FIELD_RANGE(_fd, _reg, _lsb, _msb) \
  135. [_fd] = { \
  136. .name = #_fd, \
  137. .range = &mt6370_chg_ranges[MT6370_RANGE_##_fd], \
  138. .field = REG_FIELD(_reg, _lsb, _msb), \
  139. }
  140. static const struct mt6370_chg_field mt6370_chg_fields[F_MAX] = {
  141. MT6370_CHG_FIELD(F_IINLMTSEL, MT6370_REG_CHG_CTRL2, 2, 3),
  142. MT6370_CHG_FIELD(F_CFO_EN, MT6370_REG_CHG_CTRL2, 1, 1),
  143. MT6370_CHG_FIELD(F_CHG_EN, MT6370_REG_CHG_CTRL2, 0, 0),
  144. MT6370_CHG_FIELD_RANGE(F_IAICR, MT6370_REG_CHG_CTRL3, 2, 7),
  145. MT6370_CHG_FIELD(F_AICR_EN, MT6370_REG_CHG_CTRL3, 1, 1),
  146. MT6370_CHG_FIELD(F_ILIM_EN, MT6370_REG_CHG_CTRL3, 0, 0),
  147. MT6370_CHG_FIELD_RANGE(F_VOREG, MT6370_REG_CHG_CTRL4, 1, 7),
  148. MT6370_CHG_FIELD_RANGE(F_VMIVR, MT6370_REG_CHG_CTRL6, 1, 7),
  149. MT6370_CHG_FIELD_RANGE(F_ICHG, MT6370_REG_CHG_CTRL7, 2, 7),
  150. MT6370_CHG_FIELD_RANGE(F_IPREC, MT6370_REG_CHG_CTRL8, 0, 3),
  151. MT6370_CHG_FIELD_RANGE(F_IEOC, MT6370_REG_CHG_CTRL9, 4, 7),
  152. MT6370_CHG_FIELD(F_USBCHGEN, MT6370_REG_DEVICE_TYPE, 7, 7),
  153. MT6370_CHG_FIELD(F_USB_STAT, MT6370_REG_USB_STATUS1, 4, 6),
  154. MT6370_CHG_FIELD(F_CHGDET, MT6370_REG_USB_STATUS1, 3, 3),
  155. MT6370_CHG_FIELD(F_CHG_STAT, MT6370_REG_CHG_STAT, 6, 7),
  156. MT6370_CHG_FIELD(F_BOOST_STAT, MT6370_REG_CHG_STAT, 3, 3),
  157. MT6370_CHG_FIELD(F_VBAT_LVL, MT6370_REG_CHG_STAT, 5, 5),
  158. MT6370_CHG_FIELD(F_FL_STROBE, MT6370_REG_FLED_EN, 2, 2),
  159. MT6370_CHG_FIELD(F_CHG_MIVR_STAT, MT6370_REG_CHG_STAT1, 6, 6),
  160. MT6370_CHG_FIELD(F_UVP_D_STAT, MT6370_REG_OVPCTRL_STAT, 4, 4),
  161. };
  162. static inline int mt6370_chg_field_get(struct mt6370_priv *priv,
  163. enum mt6370_chg_reg_field fd,
  164. unsigned int *val)
  165. {
  166. int ret;
  167. unsigned int reg_val;
  168. ret = regmap_field_read(priv->rmap_fields[fd], &reg_val);
  169. if (ret)
  170. return ret;
  171. if (mt6370_chg_fields[fd].range)
  172. return linear_range_get_value(mt6370_chg_fields[fd].range,
  173. reg_val, val);
  174. *val = reg_val;
  175. return 0;
  176. }
  177. static inline int mt6370_chg_field_set(struct mt6370_priv *priv,
  178. enum mt6370_chg_reg_field fd,
  179. unsigned int val)
  180. {
  181. int ret;
  182. bool f;
  183. const struct linear_range *r;
  184. if (mt6370_chg_fields[fd].range) {
  185. r = mt6370_chg_fields[fd].range;
  186. if (fd == F_VMIVR) {
  187. ret = linear_range_get_selector_high(r, val, &val, &f);
  188. if (ret)
  189. val = r->max_sel;
  190. } else {
  191. linear_range_get_selector_within(r, val, &val);
  192. }
  193. }
  194. return regmap_field_write(priv->rmap_fields[fd], val);
  195. }
  196. enum {
  197. MT6370_CHG_STAT_READY = 0,
  198. MT6370_CHG_STAT_CHARGE_IN_PROGRESS,
  199. MT6370_CHG_STAT_DONE,
  200. MT6370_CHG_STAT_FAULT,
  201. MT6370_CHG_STAT_MAX
  202. };
  203. enum {
  204. MT6370_ATTACH_STAT_DETACH = 0,
  205. MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12,
  206. MT6370_ATTACH_STAT_ATTACH_BC12_DONE,
  207. MT6370_ATTACH_STAT_ATTACH_MAX
  208. };
  209. static int mt6370_chg_otg_of_parse_cb(struct device_node *of,
  210. const struct regulator_desc *rdesc,
  211. struct regulator_config *rcfg)
  212. {
  213. struct mt6370_priv *priv = rcfg->driver_data;
  214. rcfg->ena_gpiod = fwnode_gpiod_get_index(of_fwnode_handle(of),
  215. "enable", 0, GPIOD_OUT_LOW |
  216. GPIOD_FLAGS_BIT_NONEXCLUSIVE,
  217. rdesc->name);
  218. if (IS_ERR(rcfg->ena_gpiod)) {
  219. rcfg->ena_gpiod = NULL;
  220. return 0;
  221. }
  222. return regmap_update_bits(priv->regmap, MT6370_REG_CHG_CTRL1,
  223. MT6370_OTG_PIN_EN_MASK,
  224. MT6370_OTG_PIN_EN_MASK);
  225. }
  226. static void mt6370_chg_bc12_work_func(struct work_struct *work)
  227. {
  228. struct mt6370_priv *priv = container_of(work, struct mt6370_priv,
  229. bc12_work);
  230. int ret;
  231. bool rpt_psy = false;
  232. unsigned int attach, usb_stat;
  233. mutex_lock(&priv->attach_lock);
  234. attach = priv->attach;
  235. switch (attach) {
  236. case MT6370_ATTACH_STAT_DETACH:
  237. usb_stat = 0;
  238. break;
  239. case MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12:
  240. ret = mt6370_chg_field_set(priv, F_USBCHGEN, attach);
  241. if (ret)
  242. dev_err(priv->dev, "Failed to enable USB CHG EN\n");
  243. goto bc12_work_func_out;
  244. case MT6370_ATTACH_STAT_ATTACH_BC12_DONE:
  245. ret = mt6370_chg_field_get(priv, F_USB_STAT, &usb_stat);
  246. if (ret) {
  247. dev_err(priv->dev, "Failed to get USB status\n");
  248. goto bc12_work_func_out;
  249. }
  250. break;
  251. default:
  252. dev_err(priv->dev, "Invalid attach state\n");
  253. goto bc12_work_func_out;
  254. }
  255. rpt_psy = true;
  256. switch (usb_stat) {
  257. case MT6370_USB_STAT_SDP:
  258. case MT6370_USB_STAT_SDP_NSTD:
  259. priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_SDP;
  260. break;
  261. case MT6370_USB_STAT_DCP:
  262. priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_DCP;
  263. break;
  264. case MT6370_USB_STAT_CDP:
  265. priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_CDP;
  266. break;
  267. case MT6370_USB_STAT_NO_VBUS:
  268. case MT6370_USB_STAT_VBUS_FLOW_IS_UNDER_GOING:
  269. default:
  270. priv->psy_usb_type = POWER_SUPPLY_USB_TYPE_UNKNOWN;
  271. break;
  272. }
  273. bc12_work_func_out:
  274. mutex_unlock(&priv->attach_lock);
  275. if (rpt_psy)
  276. power_supply_changed(priv->psy);
  277. }
  278. static int mt6370_chg_toggle_cfo(struct mt6370_priv *priv)
  279. {
  280. int ret;
  281. unsigned int fl_strobe;
  282. /* check if flash led in strobe mode */
  283. ret = mt6370_chg_field_get(priv, F_FL_STROBE, &fl_strobe);
  284. if (ret) {
  285. dev_err(priv->dev, "Failed to get FL_STROBE_EN\n");
  286. return ret;
  287. }
  288. if (fl_strobe) {
  289. dev_err(priv->dev, "Flash led is still in strobe mode\n");
  290. return -EINVAL;
  291. }
  292. /* cfo off */
  293. ret = mt6370_chg_field_set(priv, F_CFO_EN, 0);
  294. if (ret) {
  295. dev_err(priv->dev, "Failed to disable CFO_EN\n");
  296. return ret;
  297. }
  298. /* cfo on */
  299. ret = mt6370_chg_field_set(priv, F_CFO_EN, 1);
  300. if (ret)
  301. dev_err(priv->dev, "Failed to enable CFO_EN\n");
  302. return ret;
  303. }
  304. static int mt6370_chg_read_adc_chan(struct mt6370_priv *priv, unsigned int chan,
  305. int *val)
  306. {
  307. int ret;
  308. if (chan >= MT6370_ADC_CHAN_MAX)
  309. return -EINVAL;
  310. ret = iio_read_channel_processed(&priv->iio_adcs[chan], val);
  311. if (ret)
  312. dev_err(priv->dev, "Failed to read ADC\n");
  313. return ret;
  314. }
  315. static void mt6370_chg_mivr_dwork_func(struct work_struct *work)
  316. {
  317. struct mt6370_priv *priv = container_of(work, struct mt6370_priv,
  318. mivr_dwork.work);
  319. int ret;
  320. unsigned int mivr_stat, ibus;
  321. ret = mt6370_chg_field_get(priv, F_CHG_MIVR_STAT, &mivr_stat);
  322. if (ret) {
  323. dev_err(priv->dev, "Failed to get mivr state\n");
  324. goto mivr_handler_out;
  325. }
  326. if (!mivr_stat)
  327. goto mivr_handler_out;
  328. ret = mt6370_chg_read_adc_chan(priv, MT6370_ADC_CHAN_IBUS, &ibus);
  329. if (ret) {
  330. dev_err(priv->dev, "Failed to get ibus\n");
  331. goto mivr_handler_out;
  332. }
  333. if (ibus < MT6370_MIVR_IBUS_TH_100_mA) {
  334. ret = mt6370_chg_toggle_cfo(priv);
  335. if (ret)
  336. dev_err(priv->dev, "Failed to toggle cfo\n");
  337. }
  338. mivr_handler_out:
  339. enable_irq(priv->irq_nums[MT6370_IRQ_MIVR]);
  340. pm_relax(priv->dev);
  341. }
  342. static void mt6370_chg_pwr_rdy_check(struct mt6370_priv *priv)
  343. {
  344. int ret;
  345. unsigned int opposite_pwr_rdy, otg_en;
  346. union power_supply_propval val;
  347. /* Check in OTG mode or not */
  348. ret = mt6370_chg_field_get(priv, F_BOOST_STAT, &otg_en);
  349. if (ret) {
  350. dev_err(priv->dev, "Failed to get OTG state\n");
  351. return;
  352. }
  353. if (otg_en)
  354. return;
  355. ret = mt6370_chg_field_get(priv, F_UVP_D_STAT, &opposite_pwr_rdy);
  356. if (ret) {
  357. dev_err(priv->dev, "Failed to get opposite power ready state\n");
  358. return;
  359. }
  360. val.intval = opposite_pwr_rdy ?
  361. MT6370_ATTACH_STAT_DETACH :
  362. MT6370_ATTACH_STAT_ATTACH_WAIT_FOR_BC12;
  363. ret = power_supply_set_property(priv->psy, POWER_SUPPLY_PROP_ONLINE,
  364. &val);
  365. if (ret)
  366. dev_err(priv->dev, "Failed to start attach/detach flow\n");
  367. }
  368. static int mt6370_chg_get_online(struct mt6370_priv *priv,
  369. union power_supply_propval *val)
  370. {
  371. mutex_lock(&priv->attach_lock);
  372. val->intval = !!priv->attach;
  373. mutex_unlock(&priv->attach_lock);
  374. return 0;
  375. }
  376. static int mt6370_chg_get_status(struct mt6370_priv *priv,
  377. union power_supply_propval *val)
  378. {
  379. int ret;
  380. unsigned int chg_stat;
  381. union power_supply_propval online;
  382. ret = power_supply_get_property(priv->psy, POWER_SUPPLY_PROP_ONLINE,
  383. &online);
  384. if (ret) {
  385. dev_err(priv->dev, "Failed to get online status\n");
  386. return ret;
  387. }
  388. if (!online.intval) {
  389. val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
  390. return 0;
  391. }
  392. ret = mt6370_chg_field_get(priv, F_CHG_STAT, &chg_stat);
  393. if (ret)
  394. return ret;
  395. switch (chg_stat) {
  396. case MT6370_CHG_STAT_READY:
  397. case MT6370_CHG_STAT_FAULT:
  398. val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
  399. return ret;
  400. case MT6370_CHG_STAT_CHARGE_IN_PROGRESS:
  401. val->intval = POWER_SUPPLY_STATUS_CHARGING;
  402. return ret;
  403. case MT6370_CHG_STAT_DONE:
  404. val->intval = POWER_SUPPLY_STATUS_FULL;
  405. return ret;
  406. default:
  407. val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
  408. return ret;
  409. }
  410. }
  411. static int mt6370_chg_get_charge_type(struct mt6370_priv *priv,
  412. union power_supply_propval *val)
  413. {
  414. int type, ret;
  415. unsigned int chg_stat, vbat_lvl;
  416. ret = mt6370_chg_field_get(priv, F_CHG_STAT, &chg_stat);
  417. if (ret)
  418. return ret;
  419. ret = mt6370_chg_field_get(priv, F_VBAT_LVL, &vbat_lvl);
  420. if (ret)
  421. return ret;
  422. switch (chg_stat) {
  423. case MT6370_CHG_STAT_CHARGE_IN_PROGRESS:
  424. if (vbat_lvl)
  425. type = POWER_SUPPLY_CHARGE_TYPE_FAST;
  426. else
  427. type = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
  428. break;
  429. case MT6370_CHG_STAT_READY:
  430. case MT6370_CHG_STAT_DONE:
  431. case MT6370_CHG_STAT_FAULT:
  432. default:
  433. type = POWER_SUPPLY_CHARGE_TYPE_NONE;
  434. break;
  435. }
  436. val->intval = type;
  437. return 0;
  438. }
  439. static int mt6370_chg_set_online(struct mt6370_priv *priv,
  440. const union power_supply_propval *val)
  441. {
  442. bool pwr_rdy = !!val->intval;
  443. mutex_lock(&priv->attach_lock);
  444. if (pwr_rdy == !!priv->attach) {
  445. dev_err(priv->dev, "pwr_rdy is same(%d)\n", pwr_rdy);
  446. mutex_unlock(&priv->attach_lock);
  447. return 0;
  448. }
  449. priv->attach = pwr_rdy;
  450. mutex_unlock(&priv->attach_lock);
  451. if (!queue_work(priv->wq, &priv->bc12_work))
  452. dev_err(priv->dev, "bc12 work has already queued\n");
  453. return 0;
  454. }
  455. static int mt6370_chg_get_property(struct power_supply *psy,
  456. enum power_supply_property psp,
  457. union power_supply_propval *val)
  458. {
  459. struct mt6370_priv *priv = power_supply_get_drvdata(psy);
  460. switch (psp) {
  461. case POWER_SUPPLY_PROP_ONLINE:
  462. return mt6370_chg_get_online(priv, val);
  463. case POWER_SUPPLY_PROP_STATUS:
  464. return mt6370_chg_get_status(priv, val);
  465. case POWER_SUPPLY_PROP_CHARGE_TYPE:
  466. return mt6370_chg_get_charge_type(priv, val);
  467. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
  468. return mt6370_chg_field_get(priv, F_ICHG, &val->intval);
  469. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX:
  470. val->intval = linear_range_get_max_value(&mt6370_chg_ranges[MT6370_RANGE_F_ICHG]);
  471. return 0;
  472. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
  473. return mt6370_chg_field_get(priv, F_VOREG, &val->intval);
  474. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX:
  475. val->intval = linear_range_get_max_value(&mt6370_chg_ranges[MT6370_RANGE_F_VOREG]);
  476. return 0;
  477. case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
  478. return mt6370_chg_field_get(priv, F_IAICR, &val->intval);
  479. case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
  480. return mt6370_chg_field_get(priv, F_VMIVR, &val->intval);
  481. case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
  482. return mt6370_chg_field_get(priv, F_IPREC, &val->intval);
  483. case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
  484. return mt6370_chg_field_get(priv, F_IEOC, &val->intval);
  485. case POWER_SUPPLY_PROP_USB_TYPE:
  486. val->intval = priv->psy_usb_type;
  487. return 0;
  488. default:
  489. return -EINVAL;
  490. }
  491. }
  492. static int mt6370_chg_set_property(struct power_supply *psy,
  493. enum power_supply_property psp,
  494. const union power_supply_propval *val)
  495. {
  496. struct mt6370_priv *priv = power_supply_get_drvdata(psy);
  497. switch (psp) {
  498. case POWER_SUPPLY_PROP_ONLINE:
  499. return mt6370_chg_set_online(priv, val);
  500. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
  501. return mt6370_chg_field_set(priv, F_ICHG, val->intval);
  502. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
  503. return mt6370_chg_field_set(priv, F_VOREG, val->intval);
  504. case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
  505. return mt6370_chg_field_set(priv, F_IAICR, val->intval);
  506. case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
  507. return mt6370_chg_field_set(priv, F_VMIVR, val->intval);
  508. case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
  509. return mt6370_chg_field_set(priv, F_IPREC, val->intval);
  510. case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
  511. return mt6370_chg_field_set(priv, F_IEOC, val->intval);
  512. default:
  513. return -EINVAL;
  514. }
  515. }
  516. static int mt6370_chg_property_is_writeable(struct power_supply *psy,
  517. enum power_supply_property psp)
  518. {
  519. switch (psp) {
  520. case POWER_SUPPLY_PROP_ONLINE:
  521. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT:
  522. case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE:
  523. case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT:
  524. case POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT:
  525. case POWER_SUPPLY_PROP_PRECHARGE_CURRENT:
  526. case POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT:
  527. return 1;
  528. default:
  529. return 0;
  530. }
  531. }
  532. static enum power_supply_property mt6370_chg_properties[] = {
  533. POWER_SUPPLY_PROP_ONLINE,
  534. POWER_SUPPLY_PROP_STATUS,
  535. POWER_SUPPLY_PROP_CHARGE_TYPE,
  536. POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT,
  537. POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT_MAX,
  538. POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
  539. POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE_MAX,
  540. POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
  541. POWER_SUPPLY_PROP_INPUT_VOLTAGE_LIMIT,
  542. POWER_SUPPLY_PROP_PRECHARGE_CURRENT,
  543. POWER_SUPPLY_PROP_CHARGE_TERM_CURRENT,
  544. POWER_SUPPLY_PROP_USB_TYPE,
  545. };
  546. static enum power_supply_usb_type mt6370_chg_usb_types[] = {
  547. POWER_SUPPLY_USB_TYPE_UNKNOWN,
  548. POWER_SUPPLY_USB_TYPE_SDP,
  549. POWER_SUPPLY_USB_TYPE_CDP,
  550. POWER_SUPPLY_USB_TYPE_DCP,
  551. };
  552. static const struct power_supply_desc mt6370_chg_psy_desc = {
  553. .name = "mt6370-charger",
  554. .type = POWER_SUPPLY_TYPE_USB,
  555. .properties = mt6370_chg_properties,
  556. .num_properties = ARRAY_SIZE(mt6370_chg_properties),
  557. .get_property = mt6370_chg_get_property,
  558. .set_property = mt6370_chg_set_property,
  559. .property_is_writeable = mt6370_chg_property_is_writeable,
  560. .usb_types = mt6370_chg_usb_types,
  561. .num_usb_types = ARRAY_SIZE(mt6370_chg_usb_types),
  562. };
  563. static const struct regulator_ops mt6370_chg_otg_ops = {
  564. .list_voltage = regulator_list_voltage_linear,
  565. .enable = regulator_enable_regmap,
  566. .disable = regulator_disable_regmap,
  567. .is_enabled = regulator_is_enabled_regmap,
  568. .set_voltage_sel = regulator_set_voltage_sel_regmap,
  569. .get_voltage_sel = regulator_get_voltage_sel_regmap,
  570. .set_current_limit = regulator_set_current_limit_regmap,
  571. .get_current_limit = regulator_get_current_limit_regmap,
  572. };
  573. static const u32 mt6370_chg_otg_oc_ma[] = {
  574. 500000, 700000, 1100000, 1300000, 1800000, 2100000, 2400000,
  575. };
  576. static const struct regulator_desc mt6370_chg_otg_rdesc = {
  577. .of_match = "usb-otg-vbus-regulator",
  578. .of_parse_cb = mt6370_chg_otg_of_parse_cb,
  579. .name = "mt6370-usb-otg-vbus",
  580. .ops = &mt6370_chg_otg_ops,
  581. .owner = THIS_MODULE,
  582. .type = REGULATOR_VOLTAGE,
  583. .min_uV = 4425000,
  584. .uV_step = 25000,
  585. .n_voltages = 57,
  586. .vsel_reg = MT6370_REG_CHG_CTRL5,
  587. .vsel_mask = MT6370_VOBST_MASK,
  588. .enable_reg = MT6370_REG_CHG_CTRL1,
  589. .enable_mask = MT6370_OPA_MODE_MASK,
  590. .curr_table = mt6370_chg_otg_oc_ma,
  591. .n_current_limits = ARRAY_SIZE(mt6370_chg_otg_oc_ma),
  592. .csel_reg = MT6370_REG_CHG_CTRL10,
  593. .csel_mask = MT6370_OTG_OC_MASK,
  594. };
  595. static int mt6370_chg_init_rmap_fields(struct mt6370_priv *priv)
  596. {
  597. int i;
  598. const struct mt6370_chg_field *fds = mt6370_chg_fields;
  599. for (i = 0; i < F_MAX; i++) {
  600. priv->rmap_fields[i] = devm_regmap_field_alloc(priv->dev,
  601. priv->regmap,
  602. fds[i].field);
  603. if (IS_ERR(priv->rmap_fields[i]))
  604. return dev_err_probe(priv->dev,
  605. PTR_ERR(priv->rmap_fields[i]),
  606. "Failed to allocate regmapfield[%s]\n",
  607. fds[i].name);
  608. }
  609. return 0;
  610. }
  611. static int mt6370_chg_init_setting(struct mt6370_priv *priv)
  612. {
  613. int ret;
  614. /* Disable usb_chg_en */
  615. ret = mt6370_chg_field_set(priv, F_USBCHGEN, 0);
  616. if (ret) {
  617. dev_err(priv->dev, "Failed to disable usb_chg_en\n");
  618. return ret;
  619. }
  620. /* Disable input current limit */
  621. ret = mt6370_chg_field_set(priv, F_ILIM_EN, 0);
  622. if (ret) {
  623. dev_err(priv->dev, "Failed to disable input current limit\n");
  624. return ret;
  625. }
  626. /* ICHG/IEOC Workaround, ICHG can not be set less than 900mA */
  627. ret = mt6370_chg_field_set(priv, F_ICHG, 900000);
  628. if (ret) {
  629. dev_err(priv->dev, "Failed to set ICHG to 900mA");
  630. return ret;
  631. }
  632. /* Change input current limit selection to using IAICR results */
  633. ret = mt6370_chg_field_set(priv, F_IINLMTSEL, 2);
  634. if (ret) {
  635. dev_err(priv->dev, "Failed to set IINLMTSEL\n");
  636. return ret;
  637. }
  638. return 0;
  639. }
  640. #define MT6370_CHG_DT_PROP_DECL(_name, _type, _field) \
  641. { \
  642. .name = "mediatek,chg-" #_name, \
  643. .type = MT6370_PARSE_TYPE_##_type, \
  644. .fd = _field, \
  645. }
  646. static int mt6370_chg_init_otg_regulator(struct mt6370_priv *priv)
  647. {
  648. struct regulator_config rcfg = {
  649. .dev = priv->dev,
  650. .regmap = priv->regmap,
  651. .driver_data = priv,
  652. };
  653. priv->rdev = devm_regulator_register(priv->dev, &mt6370_chg_otg_rdesc,
  654. &rcfg);
  655. return PTR_ERR_OR_ZERO(priv->rdev);
  656. }
  657. static int mt6370_chg_init_psy(struct mt6370_priv *priv)
  658. {
  659. struct power_supply_config cfg = {
  660. .drv_data = priv,
  661. .of_node = dev_of_node(priv->dev),
  662. };
  663. priv->psy = devm_power_supply_register(priv->dev, &mt6370_chg_psy_desc,
  664. &cfg);
  665. return PTR_ERR_OR_ZERO(priv->psy);
  666. }
  667. static void mt6370_chg_destroy_attach_lock(void *data)
  668. {
  669. struct mutex *attach_lock = data;
  670. mutex_destroy(attach_lock);
  671. }
  672. static void mt6370_chg_destroy_wq(void *data)
  673. {
  674. struct workqueue_struct *wq = data;
  675. flush_workqueue(wq);
  676. destroy_workqueue(wq);
  677. }
  678. static irqreturn_t mt6370_attach_i_handler(int irq, void *data)
  679. {
  680. struct mt6370_priv *priv = data;
  681. unsigned int otg_en;
  682. int ret;
  683. /* Check in OTG mode or not */
  684. ret = mt6370_chg_field_get(priv, F_BOOST_STAT, &otg_en);
  685. if (ret) {
  686. dev_err(priv->dev, "Failed to get OTG state\n");
  687. return IRQ_NONE;
  688. }
  689. if (otg_en)
  690. return IRQ_HANDLED;
  691. mutex_lock(&priv->attach_lock);
  692. priv->attach = MT6370_ATTACH_STAT_ATTACH_BC12_DONE;
  693. mutex_unlock(&priv->attach_lock);
  694. if (!queue_work(priv->wq, &priv->bc12_work))
  695. dev_err(priv->dev, "bc12 work has already queued\n");
  696. return IRQ_HANDLED;
  697. }
  698. static irqreturn_t mt6370_uvp_d_evt_handler(int irq, void *data)
  699. {
  700. struct mt6370_priv *priv = data;
  701. mt6370_chg_pwr_rdy_check(priv);
  702. return IRQ_HANDLED;
  703. }
  704. static irqreturn_t mt6370_mivr_handler(int irq, void *data)
  705. {
  706. struct mt6370_priv *priv = data;
  707. pm_stay_awake(priv->dev);
  708. disable_irq_nosync(priv->irq_nums[MT6370_IRQ_MIVR]);
  709. schedule_delayed_work(&priv->mivr_dwork, msecs_to_jiffies(200));
  710. return IRQ_HANDLED;
  711. }
  712. #define MT6370_CHG_IRQ(_name) \
  713. { \
  714. .name = #_name, \
  715. .handler = mt6370_##_name##_handler, \
  716. }
  717. static int mt6370_chg_init_irq(struct mt6370_priv *priv)
  718. {
  719. int i, ret;
  720. const struct {
  721. char *name;
  722. irq_handler_t handler;
  723. } mt6370_chg_irqs[] = {
  724. MT6370_CHG_IRQ(attach_i),
  725. MT6370_CHG_IRQ(uvp_d_evt),
  726. MT6370_CHG_IRQ(mivr),
  727. };
  728. for (i = 0; i < ARRAY_SIZE(mt6370_chg_irqs); i++) {
  729. ret = platform_get_irq_byname(to_platform_device(priv->dev),
  730. mt6370_chg_irqs[i].name);
  731. if (ret < 0)
  732. return dev_err_probe(priv->dev, ret,
  733. "Failed to get irq %s\n",
  734. mt6370_chg_irqs[i].name);
  735. priv->irq_nums[i] = ret;
  736. ret = devm_request_threaded_irq(priv->dev, ret, NULL,
  737. mt6370_chg_irqs[i].handler,
  738. IRQF_TRIGGER_FALLING,
  739. dev_name(priv->dev), priv);
  740. if (ret)
  741. return dev_err_probe(priv->dev, ret,
  742. "Failed to request irq %s\n",
  743. mt6370_chg_irqs[i].name);
  744. }
  745. return 0;
  746. }
  747. static int mt6370_chg_probe(struct platform_device *pdev)
  748. {
  749. struct device *dev = &pdev->dev;
  750. struct mt6370_priv *priv;
  751. int ret;
  752. priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
  753. if (!priv)
  754. return -ENOMEM;
  755. priv->dev = &pdev->dev;
  756. priv->regmap = dev_get_regmap(pdev->dev.parent, NULL);
  757. if (!priv->regmap)
  758. return dev_err_probe(dev, -ENODEV, "Failed to get regmap\n");
  759. ret = mt6370_chg_init_rmap_fields(priv);
  760. if (ret)
  761. return dev_err_probe(dev, ret, "Failed to init regmap fields\n");
  762. platform_set_drvdata(pdev, priv);
  763. priv->iio_adcs = devm_iio_channel_get_all(priv->dev);
  764. if (IS_ERR(priv->iio_adcs))
  765. return dev_err_probe(dev, PTR_ERR(priv->iio_adcs),
  766. "Failed to get iio adc\n");
  767. ret = mt6370_chg_init_otg_regulator(priv);
  768. if (ret)
  769. return dev_err_probe(dev, ret, "Failed to init OTG regulator\n");
  770. ret = mt6370_chg_init_psy(priv);
  771. if (ret)
  772. return dev_err_probe(dev, ret, "Failed to init psy\n");
  773. mutex_init(&priv->attach_lock);
  774. ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_attach_lock,
  775. &priv->attach_lock);
  776. if (ret)
  777. return dev_err_probe(dev, ret, "Failed to init attach lock\n");
  778. priv->attach = MT6370_ATTACH_STAT_DETACH;
  779. priv->wq = create_singlethread_workqueue(dev_name(priv->dev));
  780. if (!priv->wq)
  781. return dev_err_probe(dev, -ENOMEM,
  782. "Failed to create workqueue\n");
  783. ret = devm_add_action_or_reset(dev, mt6370_chg_destroy_wq, priv->wq);
  784. if (ret)
  785. return dev_err_probe(dev, ret, "Failed to init wq\n");
  786. ret = devm_work_autocancel(dev, &priv->bc12_work, mt6370_chg_bc12_work_func);
  787. if (ret)
  788. return dev_err_probe(dev, ret, "Failed to init bc12 work\n");
  789. ret = devm_delayed_work_autocancel(dev, &priv->mivr_dwork, mt6370_chg_mivr_dwork_func);
  790. if (ret)
  791. return dev_err_probe(dev, ret, "Failed to init mivr delayed work\n");
  792. ret = mt6370_chg_init_setting(priv);
  793. if (ret)
  794. return dev_err_probe(dev, ret,
  795. "Failed to init mt6370 charger setting\n");
  796. ret = mt6370_chg_init_irq(priv);
  797. if (ret)
  798. return ret;
  799. mt6370_chg_pwr_rdy_check(priv);
  800. return 0;
  801. }
  802. static const struct of_device_id mt6370_chg_of_match[] = {
  803. { .compatible = "mediatek,mt6370-charger", },
  804. {}
  805. };
  806. MODULE_DEVICE_TABLE(of, mt6370_chg_of_match);
  807. static struct platform_driver mt6370_chg_driver = {
  808. .probe = mt6370_chg_probe,
  809. .driver = {
  810. .name = "mt6370-charger",
  811. .of_match_table = mt6370_chg_of_match,
  812. },
  813. };
  814. module_platform_driver(mt6370_chg_driver);
  815. MODULE_AUTHOR("ChiaEn Wu <[email protected]>");
  816. MODULE_DESCRIPTION("MediaTek MT6370 Charger Driver");
  817. MODULE_LICENSE("GPL v2");