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