hisi-spmi-controller.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/delay.h>
  3. #include <linux/err.h>
  4. #include <linux/interrupt.h>
  5. #include <linux/io.h>
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/of.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/seq_file.h>
  11. #include <linux/slab.h>
  12. #include <linux/spmi.h>
  13. /*
  14. * SPMI register addr
  15. */
  16. #define SPMI_CHANNEL_OFFSET 0x0300
  17. #define SPMI_SLAVE_OFFSET 0x20
  18. #define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100
  19. #define SPMI_APB_SPMI_WDATA0_BASE_ADDR 0x0104
  20. #define SPMI_APB_SPMI_WDATA1_BASE_ADDR 0x0108
  21. #define SPMI_APB_SPMI_WDATA2_BASE_ADDR 0x010c
  22. #define SPMI_APB_SPMI_WDATA3_BASE_ADDR 0x0110
  23. #define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200
  24. #define SPMI_APB_SPMI_RDATA0_BASE_ADDR 0x0204
  25. #define SPMI_APB_SPMI_RDATA1_BASE_ADDR 0x0208
  26. #define SPMI_APB_SPMI_RDATA2_BASE_ADDR 0x020c
  27. #define SPMI_APB_SPMI_RDATA3_BASE_ADDR 0x0210
  28. #define SPMI_PER_DATAREG_BYTE 4
  29. /*
  30. * SPMI cmd register
  31. */
  32. #define SPMI_APB_SPMI_CMD_EN BIT(31)
  33. #define SPMI_APB_SPMI_CMD_TYPE_OFFSET 24
  34. #define SPMI_APB_SPMI_CMD_LENGTH_OFFSET 20
  35. #define SPMI_APB_SPMI_CMD_SLAVEID_OFFSET 16
  36. #define SPMI_APB_SPMI_CMD_ADDR_OFFSET 0
  37. /* Command Opcodes */
  38. enum spmi_controller_cmd_op_code {
  39. SPMI_CMD_REG_ZERO_WRITE = 0,
  40. SPMI_CMD_REG_WRITE = 1,
  41. SPMI_CMD_REG_READ = 2,
  42. SPMI_CMD_EXT_REG_WRITE = 3,
  43. SPMI_CMD_EXT_REG_READ = 4,
  44. SPMI_CMD_EXT_REG_WRITE_L = 5,
  45. SPMI_CMD_EXT_REG_READ_L = 6,
  46. SPMI_CMD_REG_RESET = 7,
  47. SPMI_CMD_REG_SLEEP = 8,
  48. SPMI_CMD_REG_SHUTDOWN = 9,
  49. SPMI_CMD_REG_WAKEUP = 10,
  50. };
  51. /*
  52. * SPMI status register
  53. */
  54. #define SPMI_APB_TRANS_DONE BIT(0)
  55. #define SPMI_APB_TRANS_FAIL BIT(2)
  56. /* Command register fields */
  57. #define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16
  58. /* Maximum number of support PMIC peripherals */
  59. #define SPMI_CONTROLLER_TIMEOUT_US 1000
  60. #define SPMI_CONTROLLER_MAX_TRANS_BYTES 16
  61. struct spmi_controller_dev {
  62. struct spmi_controller *controller;
  63. struct device *dev;
  64. void __iomem *base;
  65. spinlock_t lock;
  66. u32 channel;
  67. };
  68. static int spmi_controller_wait_for_done(struct device *dev,
  69. struct spmi_controller_dev *ctrl_dev,
  70. void __iomem *base, u8 sid, u16 addr)
  71. {
  72. u32 timeout = SPMI_CONTROLLER_TIMEOUT_US;
  73. u32 status, offset;
  74. offset = SPMI_APB_SPMI_STATUS_BASE_ADDR;
  75. offset += SPMI_CHANNEL_OFFSET * ctrl_dev->channel + SPMI_SLAVE_OFFSET * sid;
  76. do {
  77. status = readl(base + offset);
  78. if (status & SPMI_APB_TRANS_DONE) {
  79. if (status & SPMI_APB_TRANS_FAIL) {
  80. dev_err(dev, "%s: transaction failed (0x%x)\n",
  81. __func__, status);
  82. return -EIO;
  83. }
  84. dev_dbg(dev, "%s: status 0x%x\n", __func__, status);
  85. return 0;
  86. }
  87. udelay(1);
  88. } while (timeout--);
  89. dev_err(dev, "%s: timeout, status 0x%x\n", __func__, status);
  90. return -ETIMEDOUT;
  91. }
  92. static int spmi_read_cmd(struct spmi_controller *ctrl,
  93. u8 opc, u8 slave_id, u16 slave_addr, u8 *__buf, size_t bc)
  94. {
  95. struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
  96. u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
  97. unsigned long flags;
  98. u8 *buf = __buf;
  99. u32 cmd, data;
  100. int rc;
  101. u8 op_code, i;
  102. if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
  103. dev_err(&ctrl->dev,
  104. "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
  105. SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
  106. return -EINVAL;
  107. }
  108. switch (opc) {
  109. case SPMI_CMD_READ:
  110. op_code = SPMI_CMD_REG_READ;
  111. break;
  112. case SPMI_CMD_EXT_READ:
  113. op_code = SPMI_CMD_EXT_REG_READ;
  114. break;
  115. case SPMI_CMD_EXT_READL:
  116. op_code = SPMI_CMD_EXT_REG_READ_L;
  117. break;
  118. default:
  119. dev_err(&ctrl->dev, "invalid read cmd 0x%x\n", opc);
  120. return -EINVAL;
  121. }
  122. cmd = SPMI_APB_SPMI_CMD_EN |
  123. (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
  124. ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
  125. ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) | /* slvid */
  126. ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET); /* slave_addr */
  127. spin_lock_irqsave(&spmi_controller->lock, flags);
  128. writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
  129. rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
  130. spmi_controller->base, slave_id, slave_addr);
  131. if (rc)
  132. goto done;
  133. for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
  134. data = readl(spmi_controller->base + chnl_ofst +
  135. SPMI_SLAVE_OFFSET * slave_id +
  136. SPMI_APB_SPMI_RDATA0_BASE_ADDR +
  137. i * SPMI_PER_DATAREG_BYTE);
  138. data = be32_to_cpu((__be32 __force)data);
  139. if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
  140. memcpy(buf, &data, sizeof(data));
  141. buf += sizeof(data);
  142. } else {
  143. memcpy(buf, &data, bc % SPMI_PER_DATAREG_BYTE);
  144. buf += (bc % SPMI_PER_DATAREG_BYTE);
  145. }
  146. }
  147. done:
  148. spin_unlock_irqrestore(&spmi_controller->lock, flags);
  149. if (rc)
  150. dev_err(&ctrl->dev,
  151. "spmi read wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
  152. opc, slave_id, slave_addr, bc + 1);
  153. else
  154. dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, read value: %*ph\n",
  155. __func__, slave_id, slave_addr, (int)bc, __buf);
  156. return rc;
  157. }
  158. static int spmi_write_cmd(struct spmi_controller *ctrl,
  159. u8 opc, u8 slave_id, u16 slave_addr, const u8 *__buf, size_t bc)
  160. {
  161. struct spmi_controller_dev *spmi_controller = dev_get_drvdata(&ctrl->dev);
  162. u32 chnl_ofst = SPMI_CHANNEL_OFFSET * spmi_controller->channel;
  163. const u8 *buf = __buf;
  164. unsigned long flags;
  165. u32 cmd, data;
  166. int rc;
  167. u8 op_code, i;
  168. if (bc > SPMI_CONTROLLER_MAX_TRANS_BYTES) {
  169. dev_err(&ctrl->dev,
  170. "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
  171. SPMI_CONTROLLER_MAX_TRANS_BYTES, bc);
  172. return -EINVAL;
  173. }
  174. switch (opc) {
  175. case SPMI_CMD_WRITE:
  176. op_code = SPMI_CMD_REG_WRITE;
  177. break;
  178. case SPMI_CMD_EXT_WRITE:
  179. op_code = SPMI_CMD_EXT_REG_WRITE;
  180. break;
  181. case SPMI_CMD_EXT_WRITEL:
  182. op_code = SPMI_CMD_EXT_REG_WRITE_L;
  183. break;
  184. default:
  185. dev_err(&ctrl->dev, "invalid write cmd 0x%x\n", opc);
  186. return -EINVAL;
  187. }
  188. cmd = SPMI_APB_SPMI_CMD_EN |
  189. (op_code << SPMI_APB_SPMI_CMD_TYPE_OFFSET) |
  190. ((bc - 1) << SPMI_APB_SPMI_CMD_LENGTH_OFFSET) |
  191. ((slave_id & 0xf) << SPMI_APB_SPMI_CMD_SLAVEID_OFFSET) |
  192. ((slave_addr & 0xffff) << SPMI_APB_SPMI_CMD_ADDR_OFFSET);
  193. /* Write data to FIFOs */
  194. spin_lock_irqsave(&spmi_controller->lock, flags);
  195. for (i = 0; bc > i * SPMI_PER_DATAREG_BYTE; i++) {
  196. data = 0;
  197. if ((bc - i * SPMI_PER_DATAREG_BYTE) >> 2) {
  198. memcpy(&data, buf, sizeof(data));
  199. buf += sizeof(data);
  200. } else {
  201. memcpy(&data, buf, bc % SPMI_PER_DATAREG_BYTE);
  202. buf += (bc % SPMI_PER_DATAREG_BYTE);
  203. }
  204. writel((u32 __force)cpu_to_be32(data),
  205. spmi_controller->base + chnl_ofst +
  206. SPMI_APB_SPMI_WDATA0_BASE_ADDR +
  207. SPMI_PER_DATAREG_BYTE * i);
  208. }
  209. /* Start the transaction */
  210. writel(cmd, spmi_controller->base + chnl_ofst + SPMI_APB_SPMI_CMD_BASE_ADDR);
  211. rc = spmi_controller_wait_for_done(&ctrl->dev, spmi_controller,
  212. spmi_controller->base, slave_id,
  213. slave_addr);
  214. spin_unlock_irqrestore(&spmi_controller->lock, flags);
  215. if (rc)
  216. dev_err(&ctrl->dev, "spmi write wait timeout op:0x%x slave_id:%d slave_addr:0x%x bc:%zu\n",
  217. opc, slave_id, slave_addr, bc);
  218. else
  219. dev_dbg(&ctrl->dev, "%s: id:%d slave_addr:0x%x, wrote value: %*ph\n",
  220. __func__, slave_id, slave_addr, (int)bc, __buf);
  221. return rc;
  222. }
  223. static int spmi_controller_probe(struct platform_device *pdev)
  224. {
  225. struct spmi_controller_dev *spmi_controller;
  226. struct spmi_controller *ctrl;
  227. struct resource *iores;
  228. int ret;
  229. ctrl = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
  230. if (!ctrl) {
  231. dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
  232. return -ENOMEM;
  233. }
  234. spmi_controller = spmi_controller_get_drvdata(ctrl);
  235. spmi_controller->controller = ctrl;
  236. iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  237. if (!iores) {
  238. dev_err(&pdev->dev, "can not get resource!\n");
  239. ret = -EINVAL;
  240. goto err_put_controller;
  241. }
  242. spmi_controller->base = devm_ioremap(&pdev->dev, iores->start,
  243. resource_size(iores));
  244. if (!spmi_controller->base) {
  245. dev_err(&pdev->dev, "can not remap base addr!\n");
  246. ret = -EADDRNOTAVAIL;
  247. goto err_put_controller;
  248. }
  249. ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel",
  250. &spmi_controller->channel);
  251. if (ret) {
  252. dev_err(&pdev->dev, "can not get channel\n");
  253. ret = -ENODEV;
  254. goto err_put_controller;
  255. }
  256. platform_set_drvdata(pdev, spmi_controller);
  257. dev_set_drvdata(&ctrl->dev, spmi_controller);
  258. spin_lock_init(&spmi_controller->lock);
  259. ctrl->nr = spmi_controller->channel;
  260. ctrl->dev.parent = pdev->dev.parent;
  261. ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
  262. /* Callbacks */
  263. ctrl->read_cmd = spmi_read_cmd;
  264. ctrl->write_cmd = spmi_write_cmd;
  265. ret = spmi_controller_add(ctrl);
  266. if (ret) {
  267. dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret);
  268. goto err_put_controller;
  269. }
  270. return 0;
  271. err_put_controller:
  272. spmi_controller_put(ctrl);
  273. return ret;
  274. }
  275. static int spmi_del_controller(struct platform_device *pdev)
  276. {
  277. struct spmi_controller *ctrl = platform_get_drvdata(pdev);
  278. spmi_controller_remove(ctrl);
  279. spmi_controller_put(ctrl);
  280. return 0;
  281. }
  282. static const struct of_device_id spmi_controller_match_table[] = {
  283. {
  284. .compatible = "hisilicon,kirin970-spmi-controller",
  285. },
  286. {}
  287. };
  288. MODULE_DEVICE_TABLE(of, spmi_controller_match_table);
  289. static struct platform_driver spmi_controller_driver = {
  290. .probe = spmi_controller_probe,
  291. .remove = spmi_del_controller,
  292. .driver = {
  293. .name = "hisi_spmi_controller",
  294. .of_match_table = spmi_controller_match_table,
  295. },
  296. };
  297. static int __init spmi_controller_init(void)
  298. {
  299. return platform_driver_register(&spmi_controller_driver);
  300. }
  301. postcore_initcall(spmi_controller_init);
  302. static void __exit spmi_controller_exit(void)
  303. {
  304. platform_driver_unregister(&spmi_controller_driver);
  305. }
  306. module_exit(spmi_controller_exit);
  307. MODULE_LICENSE("GPL v2");
  308. MODULE_VERSION("1.0");
  309. MODULE_ALIAS("platform:spmi_controller");