i2c-cht-wc.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Intel CHT Whiskey Cove PMIC I2C Master driver
  4. * Copyright (C) 2017 Hans de Goede <[email protected]>
  5. *
  6. * Based on various non upstream patches to support the CHT Whiskey Cove PMIC:
  7. * Copyright (C) 2011 - 2014 Intel Corporation. All rights reserved.
  8. */
  9. #include <linux/acpi.h>
  10. #include <linux/completion.h>
  11. #include <linux/delay.h>
  12. #include <linux/i2c.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/irq.h>
  15. #include <linux/irqdomain.h>
  16. #include <linux/mfd/intel_soc_pmic.h>
  17. #include <linux/module.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/power/bq24190_charger.h>
  20. #include <linux/power/bq25890_charger.h>
  21. #include <linux/slab.h>
  22. #define CHT_WC_I2C_CTRL 0x5e24
  23. #define CHT_WC_I2C_CTRL_WR BIT(0)
  24. #define CHT_WC_I2C_CTRL_RD BIT(1)
  25. #define CHT_WC_I2C_CLIENT_ADDR 0x5e25
  26. #define CHT_WC_I2C_REG_OFFSET 0x5e26
  27. #define CHT_WC_I2C_WRDATA 0x5e27
  28. #define CHT_WC_I2C_RDDATA 0x5e28
  29. #define CHT_WC_EXTCHGRIRQ 0x6e0a
  30. #define CHT_WC_EXTCHGRIRQ_CLIENT_IRQ BIT(0)
  31. #define CHT_WC_EXTCHGRIRQ_WRITE_IRQ BIT(1)
  32. #define CHT_WC_EXTCHGRIRQ_READ_IRQ BIT(2)
  33. #define CHT_WC_EXTCHGRIRQ_NACK_IRQ BIT(3)
  34. #define CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK ((u8)GENMASK(3, 1))
  35. #define CHT_WC_EXTCHGRIRQ_MSK 0x6e17
  36. struct cht_wc_i2c_adap {
  37. struct i2c_adapter adapter;
  38. wait_queue_head_t wait;
  39. struct irq_chip irqchip;
  40. struct mutex adap_lock;
  41. struct mutex irqchip_lock;
  42. struct regmap *regmap;
  43. struct irq_domain *irq_domain;
  44. struct i2c_client *client;
  45. int client_irq;
  46. u8 irq_mask;
  47. u8 old_irq_mask;
  48. int read_data;
  49. bool io_error;
  50. bool done;
  51. };
  52. static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
  53. {
  54. struct cht_wc_i2c_adap *adap = data;
  55. int ret, reg;
  56. mutex_lock(&adap->adap_lock);
  57. /* Read IRQs */
  58. ret = regmap_read(adap->regmap, CHT_WC_EXTCHGRIRQ, &reg);
  59. if (ret) {
  60. dev_err(&adap->adapter.dev, "Error reading extchgrirq reg\n");
  61. mutex_unlock(&adap->adap_lock);
  62. return IRQ_NONE;
  63. }
  64. reg &= ~adap->irq_mask;
  65. /* Reads must be acked after reading the received data. */
  66. ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, &adap->read_data);
  67. if (ret)
  68. adap->io_error = true;
  69. /*
  70. * Immediately ack IRQs, so that if new IRQs arrives while we're
  71. * handling the previous ones our irq will re-trigger when we're done.
  72. */
  73. ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, reg);
  74. if (ret)
  75. dev_err(&adap->adapter.dev, "Error writing extchgrirq reg\n");
  76. if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK) {
  77. adap->io_error |= !!(reg & CHT_WC_EXTCHGRIRQ_NACK_IRQ);
  78. adap->done = true;
  79. }
  80. mutex_unlock(&adap->adap_lock);
  81. if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK)
  82. wake_up(&adap->wait);
  83. /*
  84. * Do NOT use handle_nested_irq here, the client irq handler will
  85. * likely want to do i2c transfers and the i2c controller uses this
  86. * interrupt handler as well, so running the client irq handler from
  87. * this thread will cause things to lock up.
  88. */
  89. if (reg & CHT_WC_EXTCHGRIRQ_CLIENT_IRQ)
  90. generic_handle_irq_safe(adap->client_irq);
  91. return IRQ_HANDLED;
  92. }
  93. static u32 cht_wc_i2c_adap_master_func(struct i2c_adapter *adap)
  94. {
  95. /* This i2c adapter only supports SMBUS byte transfers */
  96. return I2C_FUNC_SMBUS_BYTE_DATA;
  97. }
  98. static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
  99. unsigned short flags, char read_write,
  100. u8 command, int size,
  101. union i2c_smbus_data *data)
  102. {
  103. struct cht_wc_i2c_adap *adap = i2c_get_adapdata(_adap);
  104. int ret;
  105. mutex_lock(&adap->adap_lock);
  106. adap->io_error = false;
  107. adap->done = false;
  108. mutex_unlock(&adap->adap_lock);
  109. ret = regmap_write(adap->regmap, CHT_WC_I2C_CLIENT_ADDR, addr);
  110. if (ret)
  111. return ret;
  112. if (read_write == I2C_SMBUS_WRITE) {
  113. ret = regmap_write(adap->regmap, CHT_WC_I2C_WRDATA, data->byte);
  114. if (ret)
  115. return ret;
  116. }
  117. ret = regmap_write(adap->regmap, CHT_WC_I2C_REG_OFFSET, command);
  118. if (ret)
  119. return ret;
  120. ret = regmap_write(adap->regmap, CHT_WC_I2C_CTRL,
  121. (read_write == I2C_SMBUS_WRITE) ?
  122. CHT_WC_I2C_CTRL_WR : CHT_WC_I2C_CTRL_RD);
  123. if (ret)
  124. return ret;
  125. ret = wait_event_timeout(adap->wait, adap->done, msecs_to_jiffies(30));
  126. if (ret == 0) {
  127. /*
  128. * The CHT GPIO controller serializes all IRQs, sometimes
  129. * causing significant delays, check status manually.
  130. */
  131. cht_wc_i2c_adap_thread_handler(0, adap);
  132. if (!adap->done)
  133. return -ETIMEDOUT;
  134. }
  135. ret = 0;
  136. mutex_lock(&adap->adap_lock);
  137. if (adap->io_error)
  138. ret = -EIO;
  139. else if (read_write == I2C_SMBUS_READ)
  140. data->byte = adap->read_data;
  141. mutex_unlock(&adap->adap_lock);
  142. return ret;
  143. }
  144. static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
  145. .functionality = cht_wc_i2c_adap_master_func,
  146. .smbus_xfer = cht_wc_i2c_adap_smbus_xfer,
  147. };
  148. /*
  149. * We are an i2c-adapter which itself is part of an i2c-client. This means that
  150. * transfers done through us take adapter->bus_lock twice, once for our parent
  151. * i2c-adapter and once to take our own bus_lock. Lockdep does not like this
  152. * nested locking, to make lockdep happy in the case of busses with muxes, the
  153. * i2c-core's i2c_adapter_lock_bus function calls:
  154. * rt_mutex_lock_nested(&adapter->bus_lock, i2c_adapter_depth(adapter));
  155. *
  156. * But i2c_adapter_depth only works when the direct parent of the adapter is
  157. * another adapter, as it is only meant for muxes. In our case there is an
  158. * i2c-client and MFD instantiated platform_device in the parent->child chain
  159. * between the 2 devices.
  160. *
  161. * So we override the default i2c_lock_operations and pass a hardcoded
  162. * depth of 1 to rt_mutex_lock_nested, to make lockdep happy.
  163. *
  164. * Note that if there were to be a mux attached to our adapter, this would
  165. * break things again since the i2c-mux code expects the root-adapter to have
  166. * a locking depth of 0. But we always have only 1 client directly attached
  167. * in the form of the Charger IC paired with the CHT Whiskey Cove PMIC.
  168. */
  169. static void cht_wc_i2c_adap_lock_bus(struct i2c_adapter *adapter,
  170. unsigned int flags)
  171. {
  172. rt_mutex_lock_nested(&adapter->bus_lock, 1);
  173. }
  174. static int cht_wc_i2c_adap_trylock_bus(struct i2c_adapter *adapter,
  175. unsigned int flags)
  176. {
  177. return rt_mutex_trylock(&adapter->bus_lock);
  178. }
  179. static void cht_wc_i2c_adap_unlock_bus(struct i2c_adapter *adapter,
  180. unsigned int flags)
  181. {
  182. rt_mutex_unlock(&adapter->bus_lock);
  183. }
  184. static const struct i2c_lock_operations cht_wc_i2c_adap_lock_ops = {
  185. .lock_bus = cht_wc_i2c_adap_lock_bus,
  186. .trylock_bus = cht_wc_i2c_adap_trylock_bus,
  187. .unlock_bus = cht_wc_i2c_adap_unlock_bus,
  188. };
  189. /**** irqchip for the client connected to the extchgr i2c adapter ****/
  190. static void cht_wc_i2c_irq_lock(struct irq_data *data)
  191. {
  192. struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
  193. mutex_lock(&adap->irqchip_lock);
  194. }
  195. static void cht_wc_i2c_irq_sync_unlock(struct irq_data *data)
  196. {
  197. struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
  198. int ret;
  199. if (adap->irq_mask != adap->old_irq_mask) {
  200. ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ_MSK,
  201. adap->irq_mask);
  202. if (ret == 0)
  203. adap->old_irq_mask = adap->irq_mask;
  204. else
  205. dev_err(&adap->adapter.dev, "Error writing EXTCHGRIRQ_MSK\n");
  206. }
  207. mutex_unlock(&adap->irqchip_lock);
  208. }
  209. static void cht_wc_i2c_irq_enable(struct irq_data *data)
  210. {
  211. struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
  212. adap->irq_mask &= ~CHT_WC_EXTCHGRIRQ_CLIENT_IRQ;
  213. }
  214. static void cht_wc_i2c_irq_disable(struct irq_data *data)
  215. {
  216. struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
  217. adap->irq_mask |= CHT_WC_EXTCHGRIRQ_CLIENT_IRQ;
  218. }
  219. static const struct irq_chip cht_wc_i2c_irq_chip = {
  220. .irq_bus_lock = cht_wc_i2c_irq_lock,
  221. .irq_bus_sync_unlock = cht_wc_i2c_irq_sync_unlock,
  222. .irq_disable = cht_wc_i2c_irq_disable,
  223. .irq_enable = cht_wc_i2c_irq_enable,
  224. .name = "cht_wc_ext_chrg_irq_chip",
  225. };
  226. /********** GPD Win / Pocket charger IC settings **********/
  227. static const char * const bq24190_suppliers[] = {
  228. "tcpm-source-psy-i2c-fusb302" };
  229. static const struct property_entry bq24190_props[] = {
  230. PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_suppliers),
  231. PROPERTY_ENTRY_BOOL("omit-battery-class"),
  232. PROPERTY_ENTRY_BOOL("disable-reset"),
  233. { }
  234. };
  235. static const struct software_node bq24190_node = {
  236. .properties = bq24190_props,
  237. };
  238. static struct regulator_consumer_supply fusb302_consumer = {
  239. .supply = "vbus",
  240. /* Must match fusb302 dev_name in intel_cht_int33fe.c */
  241. .dev_name = "i2c-fusb302",
  242. };
  243. static const struct regulator_init_data bq24190_vbus_init_data = {
  244. .constraints = {
  245. /* The name is used in intel_cht_int33fe.c do not change. */
  246. .name = "cht_wc_usb_typec_vbus",
  247. .valid_ops_mask = REGULATOR_CHANGE_STATUS,
  248. },
  249. .consumer_supplies = &fusb302_consumer,
  250. .num_consumer_supplies = 1,
  251. };
  252. static struct bq24190_platform_data bq24190_pdata = {
  253. .regulator_init_data = &bq24190_vbus_init_data,
  254. };
  255. static struct i2c_board_info gpd_win_board_info = {
  256. .type = "bq24190",
  257. .addr = 0x6b,
  258. .dev_name = "bq24190",
  259. .swnode = &bq24190_node,
  260. .platform_data = &bq24190_pdata,
  261. };
  262. /********** Xiaomi Mi Pad 2 charger IC settings **********/
  263. static struct regulator_consumer_supply bq2589x_vbus_consumer = {
  264. .supply = "vbus",
  265. .dev_name = "cht_wcove_pwrsrc",
  266. };
  267. static const struct regulator_init_data bq2589x_vbus_init_data = {
  268. .constraints = {
  269. .valid_ops_mask = REGULATOR_CHANGE_STATUS,
  270. },
  271. .consumer_supplies = &bq2589x_vbus_consumer,
  272. .num_consumer_supplies = 1,
  273. };
  274. static struct bq25890_platform_data bq2589x_pdata = {
  275. .regulator_init_data = &bq2589x_vbus_init_data,
  276. };
  277. static const struct property_entry xiaomi_mipad2_props[] = {
  278. PROPERTY_ENTRY_BOOL("linux,skip-reset"),
  279. PROPERTY_ENTRY_BOOL("linux,read-back-settings"),
  280. { }
  281. };
  282. static const struct software_node xiaomi_mipad2_node = {
  283. .properties = xiaomi_mipad2_props,
  284. };
  285. static struct i2c_board_info xiaomi_mipad2_board_info = {
  286. .type = "bq25890",
  287. .addr = 0x6a,
  288. .dev_name = "bq25890",
  289. .swnode = &xiaomi_mipad2_node,
  290. .platform_data = &bq2589x_pdata,
  291. };
  292. /********** Lenovo Yogabook YB1-X90F/-X91F/-X91L charger settings **********/
  293. static const char * const lenovo_yb1_bq25892_suppliers[] = { "cht_wcove_pwrsrc" };
  294. static const struct property_entry lenovo_yb1_bq25892_props[] = {
  295. PROPERTY_ENTRY_STRING_ARRAY("supplied-from",
  296. lenovo_yb1_bq25892_suppliers),
  297. PROPERTY_ENTRY_U32("linux,pump-express-vbus-max", 12000000),
  298. PROPERTY_ENTRY_BOOL("linux,skip-reset"),
  299. /*
  300. * The firmware sets everything to the defaults, which leads to a
  301. * somewhat low charge-current of 2048mA and worse to a battery-voltage
  302. * of 4.2V instead of 4.35V (when booted without a charger connected).
  303. * Use our own values instead of "linux,read-back-settings" to fix this.
  304. */
  305. PROPERTY_ENTRY_U32("ti,charge-current", 4224000),
  306. PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
  307. PROPERTY_ENTRY_U32("ti,termination-current", 256000),
  308. PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
  309. PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3500000),
  310. PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
  311. PROPERTY_ENTRY_U32("ti,boost-max-current", 1400000),
  312. PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
  313. { }
  314. };
  315. static const struct software_node lenovo_yb1_bq25892_node = {
  316. .properties = lenovo_yb1_bq25892_props,
  317. };
  318. static struct i2c_board_info lenovo_yogabook1_board_info = {
  319. .type = "bq25892",
  320. .addr = 0x6b,
  321. .dev_name = "bq25892",
  322. .swnode = &lenovo_yb1_bq25892_node,
  323. .platform_data = &bq2589x_pdata,
  324. };
  325. static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
  326. {
  327. struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
  328. struct i2c_board_info *board_info = NULL;
  329. struct cht_wc_i2c_adap *adap;
  330. int ret, reg, irq;
  331. irq = platform_get_irq(pdev, 0);
  332. if (irq < 0)
  333. return irq;
  334. adap = devm_kzalloc(&pdev->dev, sizeof(*adap), GFP_KERNEL);
  335. if (!adap)
  336. return -ENOMEM;
  337. init_waitqueue_head(&adap->wait);
  338. mutex_init(&adap->adap_lock);
  339. mutex_init(&adap->irqchip_lock);
  340. adap->irqchip = cht_wc_i2c_irq_chip;
  341. adap->regmap = pmic->regmap;
  342. adap->adapter.owner = THIS_MODULE;
  343. adap->adapter.class = I2C_CLASS_HWMON;
  344. adap->adapter.algo = &cht_wc_i2c_adap_algo;
  345. adap->adapter.lock_ops = &cht_wc_i2c_adap_lock_ops;
  346. strscpy(adap->adapter.name, "PMIC I2C Adapter",
  347. sizeof(adap->adapter.name));
  348. adap->adapter.dev.parent = &pdev->dev;
  349. /* Clear and activate i2c-adapter interrupts, disable client IRQ */
  350. adap->old_irq_mask = adap->irq_mask = ~CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK;
  351. ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, &reg);
  352. if (ret)
  353. return ret;
  354. ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, ~adap->irq_mask);
  355. if (ret)
  356. return ret;
  357. ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ_MSK, adap->irq_mask);
  358. if (ret)
  359. return ret;
  360. /* Alloc and register client IRQ */
  361. adap->irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL);
  362. if (!adap->irq_domain)
  363. return -ENOMEM;
  364. adap->client_irq = irq_create_mapping(adap->irq_domain, 0);
  365. if (!adap->client_irq) {
  366. ret = -ENOMEM;
  367. goto remove_irq_domain;
  368. }
  369. irq_set_chip_data(adap->client_irq, adap);
  370. irq_set_chip_and_handler(adap->client_irq, &adap->irqchip,
  371. handle_simple_irq);
  372. ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
  373. cht_wc_i2c_adap_thread_handler,
  374. IRQF_ONESHOT, "PMIC I2C Adapter", adap);
  375. if (ret)
  376. goto remove_irq_domain;
  377. i2c_set_adapdata(&adap->adapter, adap);
  378. ret = i2c_add_adapter(&adap->adapter);
  379. if (ret)
  380. goto remove_irq_domain;
  381. switch (pmic->cht_wc_model) {
  382. case INTEL_CHT_WC_GPD_WIN_POCKET:
  383. board_info = &gpd_win_board_info;
  384. break;
  385. case INTEL_CHT_WC_XIAOMI_MIPAD2:
  386. board_info = &xiaomi_mipad2_board_info;
  387. break;
  388. case INTEL_CHT_WC_LENOVO_YOGABOOK1:
  389. board_info = &lenovo_yogabook1_board_info;
  390. break;
  391. default:
  392. dev_warn(&pdev->dev, "Unknown model, not instantiating charger device\n");
  393. break;
  394. }
  395. if (board_info) {
  396. board_info->irq = adap->client_irq;
  397. adap->client = i2c_new_client_device(&adap->adapter, board_info);
  398. if (IS_ERR(adap->client)) {
  399. ret = PTR_ERR(adap->client);
  400. goto del_adapter;
  401. }
  402. }
  403. platform_set_drvdata(pdev, adap);
  404. return 0;
  405. del_adapter:
  406. i2c_del_adapter(&adap->adapter);
  407. remove_irq_domain:
  408. irq_domain_remove(adap->irq_domain);
  409. return ret;
  410. }
  411. static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
  412. {
  413. struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
  414. i2c_unregister_device(adap->client);
  415. i2c_del_adapter(&adap->adapter);
  416. irq_domain_remove(adap->irq_domain);
  417. return 0;
  418. }
  419. static const struct platform_device_id cht_wc_i2c_adap_id_table[] = {
  420. { .name = "cht_wcove_ext_chgr" },
  421. {},
  422. };
  423. MODULE_DEVICE_TABLE(platform, cht_wc_i2c_adap_id_table);
  424. static struct platform_driver cht_wc_i2c_adap_driver = {
  425. .probe = cht_wc_i2c_adap_i2c_probe,
  426. .remove = cht_wc_i2c_adap_i2c_remove,
  427. .driver = {
  428. .name = "cht_wcove_ext_chgr",
  429. },
  430. .id_table = cht_wc_i2c_adap_id_table,
  431. };
  432. module_platform_driver(cht_wc_i2c_adap_driver);
  433. MODULE_DESCRIPTION("Intel CHT Whiskey Cove PMIC I2C Master driver");
  434. MODULE_AUTHOR("Hans de Goede <[email protected]>");
  435. MODULE_LICENSE("GPL");