SSBI: Convert SSBI to device tree
[firefly-linux-kernel-4.4.55.git] / drivers / ssbi / ssbi.c
1 /* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
2  * Copyright (c) 2010, Google Inc.
3  *
4  * Original authors: Code Aurora Forum
5  *
6  * Author: Dima Zavin <dima@android.com>
7  *  - Largely rewritten from original to not be an i2c driver.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 and
11  * only version 2 as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  */
18
19 #define pr_fmt(fmt) "%s: " fmt, __func__
20
21 #include <linux/delay.h>
22 #include <linux/err.h>
23 #include <linux/io.h>
24 #include <linux/kernel.h>
25 #include <linux/platform_device.h>
26 #include <linux/slab.h>
27 #include <linux/msm_ssbi.h>
28 #include <linux/module.h>
29 #include <linux/of.h>
30 #include <linux/of_device.h>
31
32 /* SSBI 2.0 controller registers */
33 #define SSBI2_CMD                       0x0008
34 #define SSBI2_RD                        0x0010
35 #define SSBI2_STATUS                    0x0014
36 #define SSBI2_MODE2                     0x001C
37
38 /* SSBI_CMD fields */
39 #define SSBI_CMD_RDWRN                  (1 << 24)
40
41 /* SSBI_STATUS fields */
42 #define SSBI_STATUS_RD_READY            (1 << 2)
43 #define SSBI_STATUS_READY               (1 << 1)
44 #define SSBI_STATUS_MCHN_BUSY           (1 << 0)
45
46 /* SSBI_MODE2 fields */
47 #define SSBI_MODE2_REG_ADDR_15_8_SHFT   0x04
48 #define SSBI_MODE2_REG_ADDR_15_8_MASK   (0x7f << SSBI_MODE2_REG_ADDR_15_8_SHFT)
49
50 #define SET_SSBI_MODE2_REG_ADDR_15_8(MD, AD) \
51         (((MD) & 0x0F) | ((((AD) >> 8) << SSBI_MODE2_REG_ADDR_15_8_SHFT) & \
52         SSBI_MODE2_REG_ADDR_15_8_MASK))
53
54 /* SSBI PMIC Arbiter command registers */
55 #define SSBI_PA_CMD                     0x0000
56 #define SSBI_PA_RD_STATUS               0x0004
57
58 /* SSBI_PA_CMD fields */
59 #define SSBI_PA_CMD_RDWRN               (1 << 24)
60 #define SSBI_PA_CMD_ADDR_MASK           0x7fff /* REG_ADDR_7_0, REG_ADDR_8_14*/
61
62 /* SSBI_PA_RD_STATUS fields */
63 #define SSBI_PA_RD_STATUS_TRANS_DONE    (1 << 27)
64 #define SSBI_PA_RD_STATUS_TRANS_DENIED  (1 << 26)
65
66 #define SSBI_TIMEOUT_US                 100
67
68 struct msm_ssbi {
69         struct device           *dev;
70         struct device           *slave;
71         void __iomem            *base;
72         spinlock_t              lock;
73         enum msm_ssbi_controller_type controller_type;
74         int (*read)(struct msm_ssbi *, u16 addr, u8 *buf, int len);
75         int (*write)(struct msm_ssbi *, u16 addr, u8 *buf, int len);
76 };
77
78 #define to_msm_ssbi(dev)        platform_get_drvdata(to_platform_device(dev))
79
80 static inline u32 ssbi_readl(struct msm_ssbi *ssbi, u32 reg)
81 {
82         return readl(ssbi->base + reg);
83 }
84
85 static inline void ssbi_writel(struct msm_ssbi *ssbi, u32 val, u32 reg)
86 {
87         writel(val, ssbi->base + reg);
88 }
89
90 static int ssbi_wait_mask(struct msm_ssbi *ssbi, u32 set_mask, u32 clr_mask)
91 {
92         u32 timeout = SSBI_TIMEOUT_US;
93         u32 val;
94
95         while (timeout--) {
96                 val = ssbi_readl(ssbi, SSBI2_STATUS);
97                 if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
98                         return 0;
99                 udelay(1);
100         }
101
102         dev_err(ssbi->dev, "%s: timeout (status %x set_mask %x clr_mask %x)\n",
103                 __func__, ssbi_readl(ssbi, SSBI2_STATUS), set_mask, clr_mask);
104         return -ETIMEDOUT;
105 }
106
107 static int
108 msm_ssbi_read_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
109 {
110         u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
111         int ret = 0;
112
113         if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
114                 u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
115                 mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
116                 ssbi_writel(ssbi, mode2, SSBI2_MODE2);
117         }
118
119         while (len) {
120                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
121                 if (ret)
122                         goto err;
123
124                 ssbi_writel(ssbi, cmd, SSBI2_CMD);
125                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
126                 if (ret)
127                         goto err;
128                 *buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
129                 len--;
130         }
131
132 err:
133         return ret;
134 }
135
136 static int
137 msm_ssbi_write_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
138 {
139         int ret = 0;
140
141         if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
142                 u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
143                 mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
144                 ssbi_writel(ssbi, mode2, SSBI2_MODE2);
145         }
146
147         while (len) {
148                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
149                 if (ret)
150                         goto err;
151
152                 ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
153                 ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
154                 if (ret)
155                         goto err;
156                 buf++;
157                 len--;
158         }
159
160 err:
161         return ret;
162 }
163
164 static inline int
165 msm_ssbi_pa_transfer(struct msm_ssbi *ssbi, u32 cmd, u8 *data)
166 {
167         u32 timeout = SSBI_TIMEOUT_US;
168         u32 rd_status = 0;
169
170         ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
171
172         while (timeout--) {
173                 rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
174
175                 if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED) {
176                         dev_err(ssbi->dev, "%s: transaction denied (0x%x)\n",
177                                         __func__, rd_status);
178                         return -EPERM;
179                 }
180
181                 if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
182                         if (data)
183                                 *data = rd_status & 0xff;
184                         return 0;
185                 }
186                 udelay(1);
187         }
188
189         dev_err(ssbi->dev, "%s: timeout, status 0x%x\n", __func__, rd_status);
190         return -ETIMEDOUT;
191 }
192
193 static int
194 msm_ssbi_pa_read_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
195 {
196         u32 cmd;
197         int ret = 0;
198
199         cmd = SSBI_PA_CMD_RDWRN | (addr & SSBI_PA_CMD_ADDR_MASK) << 8;
200
201         while (len) {
202                 ret = msm_ssbi_pa_transfer(ssbi, cmd, buf);
203                 if (ret)
204                         goto err;
205                 buf++;
206                 len--;
207         }
208
209 err:
210         return ret;
211 }
212
213 static int
214 msm_ssbi_pa_write_bytes(struct msm_ssbi *ssbi, u16 addr, u8 *buf, int len)
215 {
216         u32 cmd;
217         int ret = 0;
218
219         while (len) {
220                 cmd = (addr & SSBI_PA_CMD_ADDR_MASK) << 8 | *buf;
221                 ret = msm_ssbi_pa_transfer(ssbi, cmd, NULL);
222                 if (ret)
223                         goto err;
224                 buf++;
225                 len--;
226         }
227
228 err:
229         return ret;
230 }
231
232 int msm_ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
233 {
234         struct msm_ssbi *ssbi = to_msm_ssbi(dev);
235         unsigned long flags;
236         int ret;
237
238         if (ssbi->dev != dev)
239                 return -ENXIO;
240
241         spin_lock_irqsave(&ssbi->lock, flags);
242         ret = ssbi->read(ssbi, addr, buf, len);
243         spin_unlock_irqrestore(&ssbi->lock, flags);
244
245         return ret;
246 }
247 EXPORT_SYMBOL_GPL(msm_ssbi_read);
248
249 int msm_ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
250 {
251         struct msm_ssbi *ssbi = to_msm_ssbi(dev);
252         unsigned long flags;
253         int ret;
254
255         if (ssbi->dev != dev)
256                 return -ENXIO;
257
258         spin_lock_irqsave(&ssbi->lock, flags);
259         ret = ssbi->write(ssbi, addr, buf, len);
260         spin_unlock_irqrestore(&ssbi->lock, flags);
261
262         return ret;
263 }
264 EXPORT_SYMBOL_GPL(msm_ssbi_write);
265
266 static int msm_ssbi_probe(struct platform_device *pdev)
267 {
268         struct device_node *np = pdev->dev.of_node;
269         struct resource *mem_res;
270         struct msm_ssbi *ssbi;
271         int ret = 0;
272         const char *type;
273
274         ssbi = kzalloc(sizeof(struct msm_ssbi), GFP_KERNEL);
275         if (!ssbi) {
276                 pr_err("can not allocate ssbi_data\n");
277                 return -ENOMEM;
278         }
279
280         mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281         if (!mem_res) {
282                 pr_err("missing mem resource\n");
283                 ret = -EINVAL;
284                 goto err_get_mem_res;
285         }
286
287         ssbi->base = ioremap(mem_res->start, resource_size(mem_res));
288         if (!ssbi->base) {
289                 pr_err("ioremap of 0x%p failed\n", (void *)mem_res->start);
290                 ret = -EINVAL;
291                 goto err_ioremap;
292         }
293         ssbi->dev = &pdev->dev;
294         platform_set_drvdata(pdev, ssbi);
295
296         type = of_get_property(np, "qcom,controller-type", NULL);
297         if (type == NULL) {
298                 pr_err("Missing qcom,controller-type property\n");
299                 ret = -EINVAL;
300                 goto err_ssbi_controller;
301         }
302         dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
303         if (strcmp(type, "ssbi") == 0)
304                 ssbi->controller_type = MSM_SBI_CTRL_SSBI;
305         else if (strcmp(type, "ssbi2") == 0)
306                 ssbi->controller_type = MSM_SBI_CTRL_SSBI2;
307         else if (strcmp(type, "pmic-arbiter") == 0)
308                 ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
309         else {
310                 pr_err("Unknown qcom,controller-type\n");
311                 ret = -EINVAL;
312                 goto err_ssbi_controller;
313         }
314
315         if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
316                 ssbi->read = msm_ssbi_pa_read_bytes;
317                 ssbi->write = msm_ssbi_pa_write_bytes;
318         } else {
319                 ssbi->read = msm_ssbi_read_bytes;
320                 ssbi->write = msm_ssbi_write_bytes;
321         }
322
323         spin_lock_init(&ssbi->lock);
324
325         ret = of_platform_populate(np, NULL, NULL, &pdev->dev);
326         if (ret)
327                 goto err_ssbi_controller;
328
329         return 0;
330
331 err_ssbi_controller:
332         platform_set_drvdata(pdev, NULL);
333         iounmap(ssbi->base);
334 err_ioremap:
335 err_get_mem_res:
336         kfree(ssbi);
337         return ret;
338 }
339
340 static int msm_ssbi_remove(struct platform_device *pdev)
341 {
342         struct msm_ssbi *ssbi = platform_get_drvdata(pdev);
343
344         platform_set_drvdata(pdev, NULL);
345         iounmap(ssbi->base);
346         kfree(ssbi);
347         return 0;
348 }
349
350 static struct of_device_id ssbi_match_table[] = {
351         { .compatible = "qcom,ssbi" },
352         {}
353 };
354
355 static struct platform_driver msm_ssbi_driver = {
356         .probe          = msm_ssbi_probe,
357         .remove         = msm_ssbi_remove,
358         .driver         = {
359                 .name   = "msm_ssbi",
360                 .owner  = THIS_MODULE,
361                 .of_match_table = ssbi_match_table,
362         },
363 };
364
365 static int __init msm_ssbi_init(void)
366 {
367         return platform_driver_register(&msm_ssbi_driver);
368 }
369 postcore_initcall(msm_ssbi_init);
370
371 static void __exit msm_ssbi_exit(void)
372 {
373         platform_driver_unregister(&msm_ssbi_driver);
374 }
375 module_exit(msm_ssbi_exit)
376
377 MODULE_LICENSE("GPL v2");
378 MODULE_VERSION("1.0");
379 MODULE_ALIAS("platform:msm_ssbi");
380 MODULE_AUTHOR("Dima Zavin <dima@android.com>");