]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/powerpc/mpc85xx/i2c.c
powerpc: Clamp MAXCPU for MPC85XXSPE kernel to 2
[FreeBSD/FreeBSD.git] / sys / powerpc / mpc85xx / i2c.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (C) 2008-2009 Semihalf, Michal Hajduk
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/resource.h>
38
39 #include <machine/bus.h>
40 #include <machine/resource.h>
41 #include <sys/rman.h>
42
43 #include <sys/lock.h>
44 #include <sys/mutex.h>
45
46 #include <dev/iicbus/iiconf.h>
47 #include <dev/iicbus/iicbus.h>
48 #include "iicbus_if.h"
49
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52
53 #define I2C_ADDR_REG            0x00 /* I2C slave address register */
54 #define I2C_FDR_REG             0x04 /* I2C frequency divider register */
55 #define I2C_CONTROL_REG         0x08 /* I2C control register */
56 #define I2C_STATUS_REG          0x0C /* I2C status register */
57 #define I2C_DATA_REG            0x10 /* I2C data register */
58 #define I2C_DFSRR_REG           0x14 /* I2C Digital Filter Sampling rate */
59 #define I2C_ENABLE              0x80 /* Module enable - interrupt disable */
60 #define I2CSR_RXAK              0x01 /* Received acknowledge */
61 #define I2CSR_MCF               (1<<7) /* Data transfer */
62 #define I2CSR_MASS              (1<<6) /* Addressed as a slave */
63 #define I2CSR_MBB               (1<<5) /* Bus busy */
64 #define I2CSR_MAL               (1<<4) /* Arbitration lost */
65 #define I2CSR_SRW               (1<<2) /* Slave read/write */
66 #define I2CSR_MIF               (1<<1) /* Module interrupt */
67 #define I2CCR_MEN               (1<<7) /* Module enable */
68 #define I2CCR_MSTA              (1<<5) /* Master/slave mode */
69 #define I2CCR_MTX               (1<<4) /* Transmit/receive mode */
70 #define I2CCR_TXAK              (1<<3) /* Transfer acknowledge */
71 #define I2CCR_RSTA              (1<<2) /* Repeated START */
72
73 #define I2C_BAUD_RATE_FAST      0x31
74 #define I2C_BAUD_RATE_DEF       0x3F
75 #define I2C_DFSSR_DIV           0x10
76
77 #ifdef  DEBUG
78 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt,##args); } while (0)
79 #else
80 #define debugf(fmt, args...)
81 #endif
82
83 struct i2c_softc {
84         device_t                dev;
85         device_t                iicbus;
86         struct resource         *res;
87         struct mtx              mutex;
88         int                     rid;
89         bus_space_handle_t      bsh;
90         bus_space_tag_t         bst;
91 };
92
93 static int i2c_probe(device_t);
94 static int i2c_attach(device_t);
95
96 static int i2c_repeated_start(device_t dev, u_char slave, int timeout);
97 static int i2c_start(device_t dev, u_char slave, int timeout);
98 static int i2c_stop(device_t dev);
99 static int i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr);
100 static int i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay);
101 static int i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout);
102 static phandle_t i2c_get_node(device_t bus, device_t dev);
103
104 static device_method_t i2c_methods[] = {
105         DEVMETHOD(device_probe,                 i2c_probe),
106         DEVMETHOD(device_attach,                i2c_attach),
107
108         DEVMETHOD(iicbus_callback,              iicbus_null_callback),
109         DEVMETHOD(iicbus_repeated_start,        i2c_repeated_start),
110         DEVMETHOD(iicbus_start,                 i2c_start),
111         DEVMETHOD(iicbus_stop,                  i2c_stop),
112         DEVMETHOD(iicbus_reset,                 i2c_reset),
113         DEVMETHOD(iicbus_read,                  i2c_read),
114         DEVMETHOD(iicbus_write,                 i2c_write),
115         DEVMETHOD(iicbus_transfer,              iicbus_transfer_gen),
116         DEVMETHOD(ofw_bus_get_node,             i2c_get_node),
117
118         { 0, 0 }
119 };
120
121 static driver_t i2c_driver = {
122         "iichb",
123         i2c_methods,
124         sizeof(struct i2c_softc),
125 };
126 static devclass_t  i2c_devclass;
127
128 DRIVER_MODULE(i2c, simplebus, i2c_driver, i2c_devclass, 0, 0);
129 DRIVER_MODULE(iicbus, i2c, iicbus_driver, iicbus_devclass, 0, 0);
130
131 static __inline void
132 i2c_write_reg(struct i2c_softc *sc, bus_size_t off, uint8_t val)
133 {
134
135         bus_space_write_1(sc->bst, sc->bsh, off, val);
136 }
137
138 static __inline uint8_t
139 i2c_read_reg(struct i2c_softc *sc, bus_size_t off)
140 {
141
142         return (bus_space_read_1(sc->bst, sc->bsh, off));
143 }
144
145 static __inline void
146 i2c_flag_set(struct i2c_softc *sc, bus_size_t off, uint8_t mask)
147 {
148         uint8_t status;
149
150         status = i2c_read_reg(sc, off);
151         status |= mask;
152         i2c_write_reg(sc, off, status);
153 }
154
155 static int
156 i2c_do_wait(device_t dev, struct i2c_softc *sc, int write, int start)
157 {
158         int err;
159         uint8_t status;
160
161         status = i2c_read_reg(sc, I2C_STATUS_REG);
162         if (status & I2CSR_MIF) {
163                 if (write && start && (status & I2CSR_RXAK)) {
164                         debugf("no ack %s", start ?
165                             "after sending slave address" : "");
166                         err = IIC_ENOACK;
167                         goto error;
168                 }
169                 if (status & I2CSR_MAL) {
170                         debugf("arbitration lost");
171                         err = IIC_EBUSERR;
172                         goto error;
173                 }
174                 if (!write && !(status & I2CSR_MCF)) {
175                         debugf("transfer unfinished");
176                         err = IIC_EBUSERR;
177                         goto error;
178                 }
179         }
180
181         return (IIC_NOERR);
182
183 error:
184         i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
185         i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
186         return (err);
187 }
188
189 static int
190 i2c_probe(device_t dev)
191 {
192         struct i2c_softc *sc;
193
194         if (!ofw_bus_is_compatible(dev, "fsl-i2c"))
195                 return (ENXIO);
196
197         sc = device_get_softc(dev);
198         sc->rid = 0;
199
200         sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
201             RF_ACTIVE);
202         if (sc->res == NULL) {
203                 device_printf(dev, "could not allocate resources\n");
204                 return (ENXIO);
205         }
206
207         sc->bst = rman_get_bustag(sc->res);
208         sc->bsh = rman_get_bushandle(sc->res);
209
210         /* Enable I2C */
211         i2c_write_reg(sc, I2C_CONTROL_REG, I2C_ENABLE);
212         bus_release_resource(dev, SYS_RES_MEMORY, sc->rid, sc->res);
213         device_set_desc(dev, "I2C bus controller");
214
215         return (BUS_PROBE_DEFAULT);
216 }
217
218 static int
219 i2c_attach(device_t dev)
220 {
221         struct i2c_softc *sc;
222         sc = device_get_softc(dev);
223
224         sc->dev = dev;
225         sc->rid = 0;
226
227         mtx_init(&sc->mutex, device_get_nameunit(dev), "I2C", MTX_DEF);
228
229         sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->rid,
230             RF_ACTIVE);
231         if (sc->res == NULL) {
232                 device_printf(dev, "could not allocate resources");
233                 mtx_destroy(&sc->mutex);
234                 return (ENXIO);
235         }
236
237         sc->bst = rman_get_bustag(sc->res);
238         sc->bsh = rman_get_bushandle(sc->res);
239
240         sc->iicbus = device_add_child(dev, "iicbus", -1);
241         if (sc->iicbus == NULL) {
242                 device_printf(dev, "could not add iicbus child");
243                 mtx_destroy(&sc->mutex);
244                 return (ENXIO);
245         }
246
247         bus_generic_attach(dev);
248         return (IIC_NOERR);
249 }
250 static int
251 i2c_repeated_start(device_t dev, u_char slave, int timeout)
252 {
253         struct i2c_softc *sc;
254         int error;
255         
256         sc = device_get_softc(dev);
257
258         mtx_lock(&sc->mutex);
259         /* Set repeated start condition */
260         i2c_flag_set(sc, I2C_CONTROL_REG ,I2CCR_RSTA);
261         /* Write target address - LSB is R/W bit */
262         i2c_write_reg(sc, I2C_DATA_REG, slave);
263         DELAY(1250);
264
265         error = i2c_do_wait(dev, sc, 1, 1);
266         mtx_unlock(&sc->mutex);
267
268         if (error)
269                 return (error);
270
271         return (IIC_NOERR);
272 }
273
274 static int
275 i2c_start(device_t dev, u_char slave, int timeout)
276 {
277         struct i2c_softc *sc;
278         uint8_t status;
279         int error;
280
281         sc = device_get_softc(dev);
282         DELAY(1000);
283
284         mtx_lock(&sc->mutex);
285         status = i2c_read_reg(sc, I2C_STATUS_REG);
286         /* Check if bus is idle or busy */
287         if (status & I2CSR_MBB) {
288                 debugf("bus busy");
289                 mtx_unlock(&sc->mutex);
290                 i2c_stop(dev);
291                 return (IIC_EBUSERR);
292         }
293
294         /* Set start condition */
295         i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_MSTA | I2CCR_MTX);
296         /* Write target address - LSB is R/W bit */
297         i2c_write_reg(sc, I2C_DATA_REG, slave);
298         DELAY(1250);
299
300         error = i2c_do_wait(dev, sc, 1, 1);
301
302         mtx_unlock(&sc->mutex);
303         if (error)
304                 return (error);
305
306         return (IIC_NOERR);
307 }
308
309 static int
310 i2c_stop(device_t dev)
311 {
312         struct i2c_softc *sc;
313
314         sc = device_get_softc(dev);
315         mtx_lock(&sc->mutex);
316         i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN | I2CCR_TXAK);
317         DELAY(1000);
318         mtx_unlock(&sc->mutex);
319
320         return (IIC_NOERR);
321 }
322
323 static int
324 i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldadr)
325 {
326         struct i2c_softc *sc;
327         uint8_t baud_rate;
328
329         sc = device_get_softc(dev);
330
331         switch (speed) {
332         case IIC_FAST:
333                 baud_rate = I2C_BAUD_RATE_FAST;
334                 break;
335         case IIC_SLOW:
336         case IIC_UNKNOWN:
337         case IIC_FASTEST:
338         default:
339                 baud_rate = I2C_BAUD_RATE_DEF;
340                 break;
341         }
342
343         mtx_lock(&sc->mutex);
344         i2c_write_reg(sc, I2C_CONTROL_REG, 0x0);
345         i2c_write_reg(sc, I2C_STATUS_REG, 0x0);
346         DELAY(1000);
347         i2c_write_reg(sc, I2C_FDR_REG, baud_rate);
348         i2c_write_reg(sc, I2C_DFSRR_REG, I2C_DFSSR_DIV);
349         i2c_write_reg(sc, I2C_CONTROL_REG, I2C_ENABLE);
350         DELAY(1000);
351         mtx_unlock(&sc->mutex);
352
353         return (IIC_NOERR);
354 }
355
356 static int
357 i2c_read(device_t dev, char *buf, int len, int *read, int last, int delay)
358 {
359         struct i2c_softc *sc;
360         int error;
361
362         sc = device_get_softc(dev);
363         *read = 0;
364
365         mtx_lock(&sc->mutex);
366         if (len) {
367                 if (len == 1)
368                         i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
369                             I2CCR_MSTA | I2CCR_TXAK);
370
371                 else
372                         i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
373                             I2CCR_MSTA);
374
375                 /* dummy read */
376                 i2c_read_reg(sc, I2C_DATA_REG);
377                 DELAY(1000);
378         }
379
380         while (*read < len) {
381                 DELAY(1000);
382                 error = i2c_do_wait(dev, sc, 0, 0);
383                 if (error) {
384                         mtx_unlock(&sc->mutex);
385                         return (error);
386                 }
387                 if ((*read == len - 2) && last) {
388                         i2c_write_reg(sc, I2C_CONTROL_REG, I2CCR_MEN |
389                             I2CCR_MSTA | I2CCR_TXAK);
390                 }
391
392                 if ((*read == len - 1) && last) {
393                         i2c_write_reg(sc, I2C_CONTROL_REG,  I2CCR_MEN |
394                             I2CCR_TXAK);
395                 }
396
397                 *buf++ = i2c_read_reg(sc, I2C_DATA_REG);
398                 (*read)++;
399                 DELAY(1250);
400         }
401         mtx_unlock(&sc->mutex);
402
403         return (IIC_NOERR);
404 }
405
406 static int
407 i2c_write(device_t dev, const char *buf, int len, int *sent, int timeout)
408 {
409         struct i2c_softc *sc;
410         int error;
411
412         sc = device_get_softc(dev);
413         *sent = 0;
414
415         mtx_lock(&sc->mutex);
416         while (*sent < len) {
417                 i2c_write_reg(sc, I2C_DATA_REG, *buf++);
418                 DELAY(1250);
419
420                 error = i2c_do_wait(dev, sc, 1, 0);
421                 if (error) {
422                         mtx_unlock(&sc->mutex);
423                         return (error);
424                 }
425
426                 (*sent)++;
427         }
428         mtx_unlock(&sc->mutex);
429
430         return (IIC_NOERR);
431 }
432
433 static phandle_t
434 i2c_get_node(device_t bus, device_t dev)
435 {
436
437         /* Share controller node with iibus device. */
438         return (ofw_bus_get_node(bus));
439 }