1 // SPDX-License-Identifier: GPL-2.0
3 #include <linux/delay.h>
5 #include <linux/interrupt.h>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/seq_file.h>
12 #include <linux/slab.h>
13 #include <linux/spmi.h>
18 #define SPMI_CHANNEL_OFFSET 0x0300
19 #define SPMI_SLAVE_OFFSET 0x20
21 #define SPMI_APB_SPMI_CMD_BASE_ADDR 0x0100
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
28 #define SPMI_APB_SPMI_STATUS_BASE_ADDR 0x0200
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
35 #define SPMI_PER_DATAREG_BYTE 4
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
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,
62 * SPMI status register
64 #define SPMI_APB_TRANS_DONE BIT(0)
65 #define SPMI_APB_TRANS_FAIL BIT(2)
67 /* Command register fields */
68 #define SPMI_CONTROLLER_CMD_MAX_BYTE_COUNT 16
70 /* Maximum number of support PMIC peripherals */
71 #define SPMI_CONTROLLER_TIMEOUT_US 1000
72 #define SPMI_CONTROLLER_MAX_TRANS_BYTES 16
74 struct spmi_controller_dev
{
75 struct spmi_controller
*controller
;
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
)
86 u32 timeout
= SPMI_CONTROLLER_TIMEOUT_US
;
89 offset
= SPMI_APB_SPMI_STATUS_BASE_ADDR
;
90 offset
+= SPMI_CHANNEL_OFFSET
* ctrl_dev
->channel
+ SPMI_SLAVE_OFFSET
* sid
;
93 status
= readl(base
+ offset
);
95 if (status
& SPMI_APB_TRANS_DONE
) {
96 if (status
& SPMI_APB_TRANS_FAIL
) {
97 dev_err(dev
, "%s: transaction failed (0x%x)\n",
101 dev_dbg(dev
, "%s: status 0x%x\n", __func__
, status
);
107 dev_err(dev
, "%s: timeout, status 0x%x\n", __func__
, status
);
111 static int spmi_read_cmd(struct spmi_controller
*ctrl
,
112 u8 opc
, u8 slave_id
, u16 slave_addr
, u8
*__buf
, size_t bc
)
114 struct spmi_controller_dev
*spmi_controller
= dev_get_drvdata(&ctrl
->dev
);
115 u32 chnl_ofst
= SPMI_CHANNEL_OFFSET
* spmi_controller
->channel
;
122 if (bc
> SPMI_CONTROLLER_MAX_TRANS_BYTES
) {
124 "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
125 SPMI_CONTROLLER_MAX_TRANS_BYTES
, bc
);
131 op_code
= SPMI_CMD_REG_READ
;
133 case SPMI_CMD_EXT_READ
:
134 op_code
= SPMI_CMD_EXT_REG_READ
;
136 case SPMI_CMD_EXT_READL
:
137 op_code
= SPMI_CMD_EXT_REG_READ_L
;
140 dev_err(&ctrl
->dev
, "invalid read cmd 0x%x\n", opc
);
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 */
150 spin_lock_irqsave(&spmi_controller
->lock
, flags
);
152 writel(cmd
, spmi_controller
->base
+ chnl_ofst
+ SPMI_APB_SPMI_CMD_BASE_ADDR
);
154 rc
= spmi_controller_wait_for_done(&ctrl
->dev
, spmi_controller
,
155 spmi_controller
->base
, slave_id
, slave_addr
);
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
));
169 memcpy(buf
, &data
, bc
% SPMI_PER_DATAREG_BYTE
);
170 buf
+= (bc
% SPMI_PER_DATAREG_BYTE
);
175 spin_unlock_irqrestore(&spmi_controller
->lock
, flags
);
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);
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
);
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
)
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
;
198 if (bc
> SPMI_CONTROLLER_MAX_TRANS_BYTES
) {
200 "spmi_controller supports 1..%d bytes per trans, but:%zu requested\n",
201 SPMI_CONTROLLER_MAX_TRANS_BYTES
, bc
);
207 op_code
= SPMI_CMD_REG_WRITE
;
209 case SPMI_CMD_EXT_WRITE
:
210 op_code
= SPMI_CMD_EXT_REG_WRITE
;
212 case SPMI_CMD_EXT_WRITEL
:
213 op_code
= SPMI_CMD_EXT_REG_WRITE_L
;
216 dev_err(&ctrl
->dev
, "invalid write cmd 0x%x\n", opc
);
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
);
226 /* Write data to FIFOs */
227 spin_lock_irqsave(&spmi_controller
->lock
, flags
);
229 for (i
= 0; bc
> i
* SPMI_PER_DATAREG_BYTE
; i
++) {
231 if ((bc
- i
* SPMI_PER_DATAREG_BYTE
) >> 2) {
232 memcpy(&data
, buf
, sizeof(data
));
235 memcpy(&data
, buf
, bc
% SPMI_PER_DATAREG_BYTE
);
236 buf
+= (bc
% SPMI_PER_DATAREG_BYTE
);
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
);
245 /* Start the transaction */
246 writel(cmd
, spmi_controller
->base
+ chnl_ofst
+ SPMI_APB_SPMI_CMD_BASE_ADDR
);
248 rc
= spmi_controller_wait_for_done(&ctrl
->dev
, spmi_controller
,
249 spmi_controller
->base
, slave_id
,
251 spin_unlock_irqrestore(&spmi_controller
->lock
, flags
);
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
);
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
);
263 static int spmi_controller_probe(struct platform_device
*pdev
)
265 struct spmi_controller_dev
*spmi_controller
;
266 struct spmi_controller
*ctrl
;
267 struct resource
*iores
;
270 ctrl
= spmi_controller_alloc(&pdev
->dev
, sizeof(*spmi_controller
));
272 dev_err(&pdev
->dev
, "can not allocate spmi_controller data\n");
275 spmi_controller
= spmi_controller_get_drvdata(ctrl
);
276 spmi_controller
->controller
= ctrl
;
278 iores
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
280 dev_err(&pdev
->dev
, "can not get resource!\n");
282 goto err_put_controller
;
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
;
293 ret
= of_property_read_u32(pdev
->dev
.of_node
, "hisilicon,spmi-channel",
294 &spmi_controller
->channel
);
296 dev_err(&pdev
->dev
, "can not get channel\n");
298 goto err_put_controller
;
301 platform_set_drvdata(pdev
, spmi_controller
);
302 dev_set_drvdata(&ctrl
->dev
, spmi_controller
);
304 spin_lock_init(&spmi_controller
->lock
);
306 ctrl
->nr
= spmi_controller
->channel
;
307 ctrl
->dev
.parent
= pdev
->dev
.parent
;
308 ctrl
->dev
.of_node
= of_node_get(pdev
->dev
.of_node
);
311 ctrl
->read_cmd
= spmi_read_cmd
;
312 ctrl
->write_cmd
= spmi_write_cmd
;
314 ret
= spmi_controller_add(ctrl
);
316 dev_err(&pdev
->dev
, "spmi_controller_add failed with error %d!\n", ret
);
317 goto err_put_controller
;
323 spmi_controller_put(ctrl
);
327 static int spmi_del_controller(struct platform_device
*pdev
)
329 struct spmi_controller
*ctrl
= platform_get_drvdata(pdev
);
331 spmi_controller_remove(ctrl
);
332 spmi_controller_put(ctrl
);
336 static const struct of_device_id spmi_controller_match_table
[] = {
338 .compatible
= "hisilicon,kirin970-spmi-controller",
342 MODULE_DEVICE_TABLE(of
, spmi_controller_match_table
);
344 static struct platform_driver spmi_controller_driver
= {
345 .probe
= spmi_controller_probe
,
346 .remove
= spmi_del_controller
,
348 .name
= "hisi_spmi_controller",
349 .of_match_table
= spmi_controller_match_table
,
353 static int __init
spmi_controller_init(void)
355 return platform_driver_register(&spmi_controller_driver
);
357 postcore_initcall(spmi_controller_init
);
359 static void __exit
spmi_controller_exit(void)
361 platform_driver_unregister(&spmi_controller_driver
);
363 module_exit(spmi_controller_exit
);
365 MODULE_LICENSE("GPL v2");
366 MODULE_VERSION("1.0");
367 MODULE_ALIAS("platform:spmi_controller");