]>
Commit | Line | Data |
---|---|---|
f3b54b9a SW |
1 | /* |
2 | * BCM2835 master mode driver | |
3 | * | |
4 | * This software is licensed under the terms of the GNU General Public | |
5 | * License version 2, as published by the Free Software Foundation, and | |
6 | * may be copied, distributed, and modified under those terms. | |
7 | * | |
8 | * This program is distributed in the hope that it will be useful, | |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
11 | * GNU General Public License for more details. | |
12 | */ | |
13 | ||
14 | #include <linux/clk.h> | |
15 | #include <linux/completion.h> | |
16 | #include <linux/err.h> | |
17 | #include <linux/i2c.h> | |
18 | #include <linux/interrupt.h> | |
19 | #include <linux/io.h> | |
20 | #include <linux/module.h> | |
21 | #include <linux/platform_device.h> | |
22 | #include <linux/slab.h> | |
23 | ||
24 | #define BCM2835_I2C_C 0x0 | |
25 | #define BCM2835_I2C_S 0x4 | |
26 | #define BCM2835_I2C_DLEN 0x8 | |
27 | #define BCM2835_I2C_A 0xc | |
28 | #define BCM2835_I2C_FIFO 0x10 | |
29 | #define BCM2835_I2C_DIV 0x14 | |
30 | #define BCM2835_I2C_DEL 0x18 | |
31 | #define BCM2835_I2C_CLKT 0x1c | |
32 | ||
33 | #define BCM2835_I2C_C_READ BIT(0) | |
34 | #define BCM2835_I2C_C_CLEAR BIT(4) /* bits 4 and 5 both clear */ | |
35 | #define BCM2835_I2C_C_ST BIT(7) | |
36 | #define BCM2835_I2C_C_INTD BIT(8) | |
37 | #define BCM2835_I2C_C_INTT BIT(9) | |
38 | #define BCM2835_I2C_C_INTR BIT(10) | |
39 | #define BCM2835_I2C_C_I2CEN BIT(15) | |
40 | ||
41 | #define BCM2835_I2C_S_TA BIT(0) | |
42 | #define BCM2835_I2C_S_DONE BIT(1) | |
43 | #define BCM2835_I2C_S_TXW BIT(2) | |
44 | #define BCM2835_I2C_S_RXR BIT(3) | |
45 | #define BCM2835_I2C_S_TXD BIT(4) | |
46 | #define BCM2835_I2C_S_RXD BIT(5) | |
47 | #define BCM2835_I2C_S_TXE BIT(6) | |
48 | #define BCM2835_I2C_S_RXF BIT(7) | |
49 | #define BCM2835_I2C_S_ERR BIT(8) | |
50 | #define BCM2835_I2C_S_CLKT BIT(9) | |
51 | #define BCM2835_I2C_S_LEN BIT(10) /* Fake bit for SW error reporting */ | |
52 | ||
a294aba1 SW |
53 | #define BCM2835_I2C_CDIV_MIN 0x0002 |
54 | #define BCM2835_I2C_CDIV_MAX 0xFFFE | |
55 | ||
f3b54b9a SW |
56 | #define BCM2835_I2C_TIMEOUT (msecs_to_jiffies(1000)) |
57 | ||
58 | struct bcm2835_i2c_dev { | |
59 | struct device *dev; | |
60 | void __iomem *regs; | |
61 | struct clk *clk; | |
62 | int irq; | |
63 | struct i2c_adapter adapter; | |
64 | struct completion completion; | |
e2474541 | 65 | struct i2c_msg *curr_msg; |
ee05fea2 | 66 | int num_msgs; |
f3b54b9a SW |
67 | u32 msg_err; |
68 | u8 *msg_buf; | |
69 | size_t msg_buf_remaining; | |
70 | }; | |
71 | ||
72 | static inline void bcm2835_i2c_writel(struct bcm2835_i2c_dev *i2c_dev, | |
73 | u32 reg, u32 val) | |
74 | { | |
75 | writel(val, i2c_dev->regs + reg); | |
76 | } | |
77 | ||
78 | static inline u32 bcm2835_i2c_readl(struct bcm2835_i2c_dev *i2c_dev, u32 reg) | |
79 | { | |
80 | return readl(i2c_dev->regs + reg); | |
81 | } | |
82 | ||
83 | static void bcm2835_fill_txfifo(struct bcm2835_i2c_dev *i2c_dev) | |
84 | { | |
85 | u32 val; | |
86 | ||
87 | while (i2c_dev->msg_buf_remaining) { | |
88 | val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); | |
89 | if (!(val & BCM2835_I2C_S_TXD)) | |
90 | break; | |
91 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_FIFO, | |
92 | *i2c_dev->msg_buf); | |
93 | i2c_dev->msg_buf++; | |
94 | i2c_dev->msg_buf_remaining--; | |
95 | } | |
96 | } | |
97 | ||
98 | static void bcm2835_drain_rxfifo(struct bcm2835_i2c_dev *i2c_dev) | |
99 | { | |
100 | u32 val; | |
101 | ||
102 | while (i2c_dev->msg_buf_remaining) { | |
103 | val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); | |
104 | if (!(val & BCM2835_I2C_S_RXD)) | |
105 | break; | |
106 | *i2c_dev->msg_buf = bcm2835_i2c_readl(i2c_dev, | |
107 | BCM2835_I2C_FIFO); | |
108 | i2c_dev->msg_buf++; | |
109 | i2c_dev->msg_buf_remaining--; | |
110 | } | |
111 | } | |
112 | ||
ee05fea2 NT |
113 | /* |
114 | * Repeated Start Condition (Sr) | |
115 | * The BCM2835 ARM Peripherals datasheet mentions a way to trigger a Sr when it | |
116 | * talks about reading from a slave with 10 bit address. This is achieved by | |
117 | * issuing a write, poll the I2CS.TA flag and wait for it to be set, and then | |
118 | * issue a read. | |
119 | * A comment in https://github.com/raspberrypi/linux/issues/254 shows how the | |
120 | * firmware actually does it using polling and says that it's a workaround for | |
121 | * a problem in the state machine. | |
122 | * It turns out that it is possible to use the TXW interrupt to know when the | |
123 | * transfer is active, provided the FIFO has not been prefilled. | |
124 | */ | |
125 | ||
126 | static void bcm2835_i2c_start_transfer(struct bcm2835_i2c_dev *i2c_dev) | |
127 | { | |
128 | u32 c = BCM2835_I2C_C_ST | BCM2835_I2C_C_I2CEN; | |
129 | struct i2c_msg *msg = i2c_dev->curr_msg; | |
130 | bool last_msg = (i2c_dev->num_msgs == 1); | |
131 | ||
132 | if (!i2c_dev->num_msgs) | |
133 | return; | |
134 | ||
135 | i2c_dev->num_msgs--; | |
136 | i2c_dev->msg_buf = msg->buf; | |
137 | i2c_dev->msg_buf_remaining = msg->len; | |
138 | ||
139 | if (msg->flags & I2C_M_RD) | |
140 | c |= BCM2835_I2C_C_READ | BCM2835_I2C_C_INTR; | |
141 | else | |
142 | c |= BCM2835_I2C_C_INTT; | |
143 | ||
144 | if (last_msg) | |
145 | c |= BCM2835_I2C_C_INTD; | |
146 | ||
147 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_A, msg->addr); | |
148 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DLEN, msg->len); | |
149 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, c); | |
150 | } | |
151 | ||
d4030d75 NT |
152 | /* |
153 | * Note about I2C_C_CLEAR on error: | |
154 | * The I2C_C_CLEAR on errors will take some time to resolve -- if you were in | |
155 | * non-idle state and I2C_C_READ, it sets an abort_rx flag and runs through | |
156 | * the state machine to send a NACK and a STOP. Since we're setting CLEAR | |
157 | * without I2CEN, that NACK will be hanging around queued up for next time | |
158 | * we start the engine. | |
159 | */ | |
160 | ||
f3b54b9a SW |
161 | static irqreturn_t bcm2835_i2c_isr(int this_irq, void *data) |
162 | { | |
163 | struct bcm2835_i2c_dev *i2c_dev = data; | |
164 | u32 val, err; | |
165 | ||
166 | val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); | |
f3b54b9a SW |
167 | |
168 | err = val & (BCM2835_I2C_S_CLKT | BCM2835_I2C_S_ERR); | |
169 | if (err) { | |
170 | i2c_dev->msg_err = err; | |
d4030d75 | 171 | goto complete; |
f3b54b9a SW |
172 | } |
173 | ||
f3b54b9a | 174 | if (val & BCM2835_I2C_S_DONE) { |
e2474541 NT |
175 | if (i2c_dev->curr_msg->flags & I2C_M_RD) { |
176 | bcm2835_drain_rxfifo(i2c_dev); | |
177 | val = bcm2835_i2c_readl(i2c_dev, BCM2835_I2C_S); | |
178 | } | |
179 | ||
180 | if ((val & BCM2835_I2C_S_RXD) || i2c_dev->msg_buf_remaining) | |
f3b54b9a SW |
181 | i2c_dev->msg_err = BCM2835_I2C_S_LEN; |
182 | else | |
183 | i2c_dev->msg_err = 0; | |
d4030d75 | 184 | goto complete; |
f3b54b9a SW |
185 | } |
186 | ||
e2474541 | 187 | if (val & BCM2835_I2C_S_TXW) { |
d4030d75 NT |
188 | if (!i2c_dev->msg_buf_remaining) { |
189 | i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; | |
190 | goto complete; | |
191 | } | |
192 | ||
f3b54b9a | 193 | bcm2835_fill_txfifo(i2c_dev); |
ee05fea2 NT |
194 | |
195 | if (i2c_dev->num_msgs && !i2c_dev->msg_buf_remaining) { | |
196 | i2c_dev->curr_msg++; | |
197 | bcm2835_i2c_start_transfer(i2c_dev); | |
198 | } | |
199 | ||
f3b54b9a SW |
200 | return IRQ_HANDLED; |
201 | } | |
202 | ||
e2474541 | 203 | if (val & BCM2835_I2C_S_RXR) { |
d4030d75 NT |
204 | if (!i2c_dev->msg_buf_remaining) { |
205 | i2c_dev->msg_err = val | BCM2835_I2C_S_LEN; | |
206 | goto complete; | |
207 | } | |
208 | ||
e2474541 NT |
209 | bcm2835_drain_rxfifo(i2c_dev); |
210 | return IRQ_HANDLED; | |
211 | } | |
212 | ||
f3b54b9a | 213 | return IRQ_NONE; |
d4030d75 NT |
214 | |
215 | complete: | |
216 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, BCM2835_I2C_C_CLEAR); | |
217 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_S, BCM2835_I2C_S_CLKT | | |
218 | BCM2835_I2C_S_ERR | BCM2835_I2C_S_DONE); | |
219 | complete(&i2c_dev->completion); | |
220 | ||
221 | return IRQ_HANDLED; | |
f3b54b9a SW |
222 | } |
223 | ||
ee05fea2 NT |
224 | static int bcm2835_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], |
225 | int num) | |
f3b54b9a | 226 | { |
ee05fea2 | 227 | struct bcm2835_i2c_dev *i2c_dev = i2c_get_adapdata(adap); |
c4dc1216 | 228 | unsigned long time_left; |
ee05fea2 | 229 | int i; |
f3b54b9a | 230 | |
ee05fea2 NT |
231 | for (i = 0; i < (num - 1); i++) |
232 | if (msgs[i].flags & I2C_M_RD) { | |
233 | dev_warn_once(i2c_dev->dev, | |
234 | "only one read message supported, has to be last\n"); | |
235 | return -EOPNOTSUPP; | |
236 | } | |
f3b54b9a | 237 | |
ee05fea2 NT |
238 | i2c_dev->curr_msg = msgs; |
239 | i2c_dev->num_msgs = num; | |
240 | reinit_completion(&i2c_dev->completion); | |
f3b54b9a | 241 | |
ee05fea2 | 242 | bcm2835_i2c_start_transfer(i2c_dev); |
f3b54b9a SW |
243 | |
244 | time_left = wait_for_completion_timeout(&i2c_dev->completion, | |
245 | BCM2835_I2C_TIMEOUT); | |
f3b54b9a | 246 | if (!time_left) { |
d4030d75 NT |
247 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, |
248 | BCM2835_I2C_C_CLEAR); | |
f3b54b9a SW |
249 | dev_err(i2c_dev->dev, "i2c transfer timed out\n"); |
250 | return -ETIMEDOUT; | |
251 | } | |
252 | ||
ee05fea2 NT |
253 | if (!i2c_dev->msg_err) |
254 | return num; | |
f3b54b9a | 255 | |
23c9540b | 256 | dev_dbg(i2c_dev->dev, "i2c transfer failed: %x\n", i2c_dev->msg_err); |
f3b54b9a SW |
257 | |
258 | if (i2c_dev->msg_err & BCM2835_I2C_S_ERR) | |
259 | return -EREMOTEIO; | |
f3b54b9a | 260 | |
ee05fea2 | 261 | return -EIO; |
f3b54b9a SW |
262 | } |
263 | ||
264 | static u32 bcm2835_i2c_func(struct i2c_adapter *adap) | |
265 | { | |
266 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | |
267 | } | |
268 | ||
269 | static const struct i2c_algorithm bcm2835_i2c_algo = { | |
270 | .master_xfer = bcm2835_i2c_xfer, | |
271 | .functionality = bcm2835_i2c_func, | |
272 | }; | |
273 | ||
4dbfb5f4 NC |
274 | /* |
275 | * This HW was reported to have problems with clock stretching: | |
276 | * http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html | |
277 | * https://www.raspberrypi.org/forums/viewtopic.php?p=146272 | |
278 | */ | |
279 | static const struct i2c_adapter_quirks bcm2835_i2c_quirks = { | |
280 | .flags = I2C_AQ_NO_CLK_STRETCH, | |
281 | }; | |
282 | ||
f3b54b9a SW |
283 | static int bcm2835_i2c_probe(struct platform_device *pdev) |
284 | { | |
285 | struct bcm2835_i2c_dev *i2c_dev; | |
ae50b1df | 286 | struct resource *mem, *irq; |
f3b54b9a SW |
287 | u32 bus_clk_rate, divider; |
288 | int ret; | |
289 | struct i2c_adapter *adap; | |
290 | ||
291 | i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL); | |
46797a2a | 292 | if (!i2c_dev) |
f3b54b9a | 293 | return -ENOMEM; |
f3b54b9a SW |
294 | platform_set_drvdata(pdev, i2c_dev); |
295 | i2c_dev->dev = &pdev->dev; | |
296 | init_completion(&i2c_dev->completion); | |
297 | ||
298 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | |
ae50b1df JH |
299 | i2c_dev->regs = devm_ioremap_resource(&pdev->dev, mem); |
300 | if (IS_ERR(i2c_dev->regs)) | |
301 | return PTR_ERR(i2c_dev->regs); | |
f3b54b9a SW |
302 | |
303 | i2c_dev->clk = devm_clk_get(&pdev->dev, NULL); | |
304 | if (IS_ERR(i2c_dev->clk)) { | |
85946abc EA |
305 | if (PTR_ERR(i2c_dev->clk) != -EPROBE_DEFER) |
306 | dev_err(&pdev->dev, "Could not get clock\n"); | |
f3b54b9a SW |
307 | return PTR_ERR(i2c_dev->clk); |
308 | } | |
309 | ||
310 | ret = of_property_read_u32(pdev->dev.of_node, "clock-frequency", | |
311 | &bus_clk_rate); | |
312 | if (ret < 0) { | |
313 | dev_warn(&pdev->dev, | |
314 | "Could not read clock-frequency property\n"); | |
315 | bus_clk_rate = 100000; | |
316 | } | |
317 | ||
318 | divider = DIV_ROUND_UP(clk_get_rate(i2c_dev->clk), bus_clk_rate); | |
319 | /* | |
320 | * Per the datasheet, the register is always interpreted as an even | |
321 | * number, by rounding down. In other words, the LSB is ignored. So, | |
322 | * if the LSB is set, increment the divider to avoid any issue. | |
323 | */ | |
324 | if (divider & 1) | |
325 | divider++; | |
a294aba1 SW |
326 | if ((divider < BCM2835_I2C_CDIV_MIN) || |
327 | (divider > BCM2835_I2C_CDIV_MAX)) { | |
328 | dev_err(&pdev->dev, "Invalid clock-frequency\n"); | |
329 | return -ENODEV; | |
330 | } | |
f3b54b9a SW |
331 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_DIV, divider); |
332 | ||
333 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | |
334 | if (!irq) { | |
335 | dev_err(&pdev->dev, "No IRQ resource\n"); | |
336 | return -ENODEV; | |
337 | } | |
338 | i2c_dev->irq = irq->start; | |
339 | ||
340 | ret = request_irq(i2c_dev->irq, bcm2835_i2c_isr, IRQF_SHARED, | |
341 | dev_name(&pdev->dev), i2c_dev); | |
342 | if (ret) { | |
343 | dev_err(&pdev->dev, "Could not request IRQ\n"); | |
344 | return -ENODEV; | |
345 | } | |
346 | ||
347 | adap = &i2c_dev->adapter; | |
348 | i2c_set_adapdata(adap, i2c_dev); | |
349 | adap->owner = THIS_MODULE; | |
37e4f91a | 350 | adap->class = I2C_CLASS_DEPRECATED; |
f3b54b9a SW |
351 | strlcpy(adap->name, "bcm2835 I2C adapter", sizeof(adap->name)); |
352 | adap->algo = &bcm2835_i2c_algo; | |
353 | adap->dev.parent = &pdev->dev; | |
07a27a00 | 354 | adap->dev.of_node = pdev->dev.of_node; |
4dbfb5f4 | 355 | adap->quirks = &bcm2835_i2c_quirks; |
f3b54b9a SW |
356 | |
357 | bcm2835_i2c_writel(i2c_dev, BCM2835_I2C_C, 0); | |
358 | ||
359 | ret = i2c_add_adapter(adap); | |
360 | if (ret) | |
361 | free_irq(i2c_dev->irq, i2c_dev); | |
362 | ||
363 | return ret; | |
364 | } | |
365 | ||
366 | static int bcm2835_i2c_remove(struct platform_device *pdev) | |
367 | { | |
368 | struct bcm2835_i2c_dev *i2c_dev = platform_get_drvdata(pdev); | |
369 | ||
370 | free_irq(i2c_dev->irq, i2c_dev); | |
371 | i2c_del_adapter(&i2c_dev->adapter); | |
372 | ||
373 | return 0; | |
374 | } | |
375 | ||
376 | static const struct of_device_id bcm2835_i2c_of_match[] = { | |
377 | { .compatible = "brcm,bcm2835-i2c" }, | |
378 | {}, | |
379 | }; | |
380 | MODULE_DEVICE_TABLE(of, bcm2835_i2c_of_match); | |
381 | ||
382 | static struct platform_driver bcm2835_i2c_driver = { | |
383 | .probe = bcm2835_i2c_probe, | |
384 | .remove = bcm2835_i2c_remove, | |
385 | .driver = { | |
386 | .name = "i2c-bcm2835", | |
f3b54b9a SW |
387 | .of_match_table = bcm2835_i2c_of_match, |
388 | }, | |
389 | }; | |
390 | module_platform_driver(bcm2835_i2c_driver); | |
391 | ||
392 | MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); | |
393 | MODULE_DESCRIPTION("BCM2835 I2C bus adapter"); | |
394 | MODULE_LICENSE("GPL v2"); | |
395 | MODULE_ALIAS("platform:i2c-bcm2835"); |