]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/mfd/ssbi.c
Merge remote-tracking branch 'samsung/for-next'
[karo-tx-linux.git] / drivers / mfd / ssbi.c
1 /* Copyright (c) 2009-2013, The Linux Foundation. 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/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 ssbi {
69         struct device           *slave;
70         void __iomem            *base;
71         spinlock_t              lock;
72         enum ssbi_controller_type controller_type;
73         int (*read)(struct ssbi *, u16 addr, u8 *buf, int len);
74         int (*write)(struct ssbi *, u16 addr, u8 *buf, int len);
75 };
76
77 #define to_ssbi(dev)    platform_get_drvdata(to_platform_device(dev))
78
79 static inline u32 ssbi_readl(struct ssbi *ssbi, u32 reg)
80 {
81         return readl(ssbi->base + reg);
82 }
83
84 static inline void ssbi_writel(struct ssbi *ssbi, u32 val, u32 reg)
85 {
86         writel(val, ssbi->base + reg);
87 }
88
89 /*
90  * Via private exchange with one of the original authors, the hardware
91  * should generally finish a transaction in about 5us.  The worst
92  * case, is when using the arbiter and both other CPUs have just
93  * started trying to use the SSBI bus will result in a time of about
94  * 20us.  It should never take longer than this.
95  *
96  * As such, this wait merely spins, with a udelay.
97  */
98 static int ssbi_wait_mask(struct ssbi *ssbi, u32 set_mask, u32 clr_mask)
99 {
100         u32 timeout = SSBI_TIMEOUT_US;
101         u32 val;
102
103         while (timeout--) {
104                 val = ssbi_readl(ssbi, SSBI2_STATUS);
105                 if (((val & set_mask) == set_mask) && ((val & clr_mask) == 0))
106                         return 0;
107                 udelay(1);
108         }
109
110         return -ETIMEDOUT;
111 }
112
113 static int
114 ssbi_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
115 {
116         u32 cmd = SSBI_CMD_RDWRN | ((addr & 0xff) << 16);
117         int ret = 0;
118
119         if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
120                 u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
121                 mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
122                 ssbi_writel(ssbi, mode2, SSBI2_MODE2);
123         }
124
125         while (len) {
126                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
127                 if (ret)
128                         goto err;
129
130                 ssbi_writel(ssbi, cmd, SSBI2_CMD);
131                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_RD_READY, 0);
132                 if (ret)
133                         goto err;
134                 *buf++ = ssbi_readl(ssbi, SSBI2_RD) & 0xff;
135                 len--;
136         }
137
138 err:
139         return ret;
140 }
141
142 static int
143 ssbi_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
144 {
145         int ret = 0;
146
147         if (ssbi->controller_type == MSM_SBI_CTRL_SSBI2) {
148                 u32 mode2 = ssbi_readl(ssbi, SSBI2_MODE2);
149                 mode2 = SET_SSBI_MODE2_REG_ADDR_15_8(mode2, addr);
150                 ssbi_writel(ssbi, mode2, SSBI2_MODE2);
151         }
152
153         while (len) {
154                 ret = ssbi_wait_mask(ssbi, SSBI_STATUS_READY, 0);
155                 if (ret)
156                         goto err;
157
158                 ssbi_writel(ssbi, ((addr & 0xff) << 16) | *buf, SSBI2_CMD);
159                 ret = ssbi_wait_mask(ssbi, 0, SSBI_STATUS_MCHN_BUSY);
160                 if (ret)
161                         goto err;
162                 buf++;
163                 len--;
164         }
165
166 err:
167         return ret;
168 }
169
170 /*
171  * See ssbi_wait_mask for an explanation of the time and the
172  * busywait.
173  */
174 static inline int
175 ssbi_pa_transfer(struct ssbi *ssbi, u32 cmd, u8 *data)
176 {
177         u32 timeout = SSBI_TIMEOUT_US;
178         u32 rd_status = 0;
179
180         ssbi_writel(ssbi, cmd, SSBI_PA_CMD);
181
182         while (timeout--) {
183                 rd_status = ssbi_readl(ssbi, SSBI_PA_RD_STATUS);
184
185                 if (rd_status & SSBI_PA_RD_STATUS_TRANS_DENIED)
186                         return -EPERM;
187
188                 if (rd_status & SSBI_PA_RD_STATUS_TRANS_DONE) {
189                         if (data)
190                                 *data = rd_status & 0xff;
191                         return 0;
192                 }
193                 udelay(1);
194         }
195
196         return -ETIMEDOUT;
197 }
198
199 static int
200 ssbi_pa_read_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
201 {
202         u32 cmd;
203         int ret = 0;
204
205         cmd = SSBI_PA_CMD_RDWRN | (addr & SSBI_PA_CMD_ADDR_MASK) << 8;
206
207         while (len) {
208                 ret = ssbi_pa_transfer(ssbi, cmd, buf);
209                 if (ret)
210                         goto err;
211                 buf++;
212                 len--;
213         }
214
215 err:
216         return ret;
217 }
218
219 static int
220 ssbi_pa_write_bytes(struct ssbi *ssbi, u16 addr, u8 *buf, int len)
221 {
222         u32 cmd;
223         int ret = 0;
224
225         while (len) {
226                 cmd = (addr & SSBI_PA_CMD_ADDR_MASK) << 8 | *buf;
227                 ret = ssbi_pa_transfer(ssbi, cmd, NULL);
228                 if (ret)
229                         goto err;
230                 buf++;
231                 len--;
232         }
233
234 err:
235         return ret;
236 }
237
238 int ssbi_read(struct device *dev, u16 addr, u8 *buf, int len)
239 {
240         struct ssbi *ssbi = to_ssbi(dev);
241         unsigned long flags;
242         int ret;
243
244         spin_lock_irqsave(&ssbi->lock, flags);
245         ret = ssbi->read(ssbi, addr, buf, len);
246         spin_unlock_irqrestore(&ssbi->lock, flags);
247
248         return ret;
249 }
250 EXPORT_SYMBOL_GPL(ssbi_read);
251
252 int ssbi_write(struct device *dev, u16 addr, u8 *buf, int len)
253 {
254         struct ssbi *ssbi = to_ssbi(dev);
255         unsigned long flags;
256         int ret;
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(ssbi_write);
265
266 static int ssbi_probe(struct platform_device *pdev)
267 {
268         struct device_node *np = pdev->dev.of_node;
269         struct resource *mem_res;
270         struct ssbi *ssbi;
271         const char *type;
272
273         ssbi = devm_kzalloc(&pdev->dev, sizeof(*ssbi), GFP_KERNEL);
274         if (!ssbi)
275                 return -ENOMEM;
276
277         mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
278         ssbi->base = devm_ioremap_resource(&pdev->dev, mem_res);
279         if (IS_ERR(ssbi->base))
280                 return PTR_ERR(ssbi->base);
281
282         platform_set_drvdata(pdev, ssbi);
283
284         type = of_get_property(np, "qcom,controller-type", NULL);
285         if (type == NULL) {
286                 dev_err(&pdev->dev, "Missing qcom,controller-type property\n");
287                 return -EINVAL;
288         }
289         dev_info(&pdev->dev, "SSBI controller type: '%s'\n", type);
290         if (strcmp(type, "ssbi") == 0)
291                 ssbi->controller_type = MSM_SBI_CTRL_SSBI;
292         else if (strcmp(type, "ssbi2") == 0)
293                 ssbi->controller_type = MSM_SBI_CTRL_SSBI2;
294         else if (strcmp(type, "pmic-arbiter") == 0)
295                 ssbi->controller_type = MSM_SBI_CTRL_PMIC_ARBITER;
296         else {
297                 dev_err(&pdev->dev, "Unknown qcom,controller-type\n");
298                 return -EINVAL;
299         }
300
301         if (ssbi->controller_type == MSM_SBI_CTRL_PMIC_ARBITER) {
302                 ssbi->read = ssbi_pa_read_bytes;
303                 ssbi->write = ssbi_pa_write_bytes;
304         } else {
305                 ssbi->read = ssbi_read_bytes;
306                 ssbi->write = ssbi_write_bytes;
307         }
308
309         spin_lock_init(&ssbi->lock);
310
311         return of_platform_populate(np, NULL, NULL, &pdev->dev);
312 }
313
314 static struct of_device_id ssbi_match_table[] = {
315         { .compatible = "qcom,ssbi" },
316         {}
317 };
318 MODULE_DEVICE_TABLE(of, ssbi_match_table);
319
320 static struct platform_driver ssbi_driver = {
321         .probe          = ssbi_probe,
322         .driver         = {
323                 .name   = "ssbi",
324                 .owner  = THIS_MODULE,
325                 .of_match_table = ssbi_match_table,
326         },
327 };
328 module_platform_driver(ssbi_driver);
329
330 MODULE_LICENSE("GPL v2");
331 MODULE_VERSION("1.0");
332 MODULE_ALIAS("platform:ssbi");
333 MODULE_AUTHOR("Dima Zavin <dima@android.com>");