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 
47 enum 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 
74 struct 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 
82 static 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 
111 static 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 
174 done:
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 
187 static 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 
263 static 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 = spmi_controller_alloc(&pdev->dev, sizeof(*spmi_controller));
271 	if (!ctrl) {
272 		dev_err(&pdev->dev, "can not allocate spmi_controller data\n");
273 		return -ENOMEM;
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 		ret = -EINVAL;
282 		goto err_put_controller;
283 	}
284 
285 	spmi_controller->base = devm_ioremap(&pdev->dev, iores->start,
286 					     resource_size(iores));
287 	if (!spmi_controller->base) {
288 		dev_err(&pdev->dev, "can not remap base addr!\n");
289 		ret = -EADDRNOTAVAIL;
290 		goto err_put_controller;
291 	}
292 
293 	ret = of_property_read_u32(pdev->dev.of_node, "hisilicon,spmi-channel",
294 				   &spmi_controller->channel);
295 	if (ret) {
296 		dev_err(&pdev->dev, "can not get channel\n");
297 		ret = -ENODEV;
298 		goto err_put_controller;
299 	}
300 
301 	platform_set_drvdata(pdev, spmi_controller);
302 	dev_set_drvdata(&ctrl->dev, spmi_controller);
303 
304 	spin_lock_init(&spmi_controller->lock);
305 
306 	ctrl->dev.parent = pdev->dev.parent;
307 	ctrl->dev.of_node = of_node_get(pdev->dev.of_node);
308 
309 	/* Callbacks */
310 	ctrl->read_cmd = spmi_read_cmd;
311 	ctrl->write_cmd = spmi_write_cmd;
312 
313 	ret = spmi_controller_add(ctrl);
314 	if (ret) {
315 		dev_err(&pdev->dev, "spmi_controller_add failed with error %d!\n", ret);
316 		goto err_put_controller;
317 	}
318 
319 	return 0;
320 
321 err_put_controller:
322 	spmi_controller_put(ctrl);
323 	return ret;
324 }
325 
326 static void spmi_del_controller(struct platform_device *pdev)
327 {
328 	struct spmi_controller *ctrl = platform_get_drvdata(pdev);
329 
330 	spmi_controller_remove(ctrl);
331 	spmi_controller_put(ctrl);
332 }
333 
334 static const struct of_device_id spmi_controller_match_table[] = {
335 	{
336 		.compatible = "hisilicon,kirin970-spmi-controller",
337 	},
338 	{}
339 };
340 MODULE_DEVICE_TABLE(of, spmi_controller_match_table);
341 
342 static struct platform_driver spmi_controller_driver = {
343 	.probe		= spmi_controller_probe,
344 	.remove_new	= spmi_del_controller,
345 	.driver		= {
346 		.name	= "hisi_spmi_controller",
347 		.of_match_table = spmi_controller_match_table,
348 	},
349 };
350 
351 static int __init spmi_controller_init(void)
352 {
353 	return platform_driver_register(&spmi_controller_driver);
354 }
355 postcore_initcall(spmi_controller_init);
356 
357 static void __exit spmi_controller_exit(void)
358 {
359 	platform_driver_unregister(&spmi_controller_driver);
360 }
361 module_exit(spmi_controller_exit);
362 
363 MODULE_LICENSE("GPL v2");
364 MODULE_VERSION("1.0");
365 MODULE_ALIAS("platform:spmi_controller");
366