Mon Jan 25 12:08:47 2021 UTC ()
NXP Layerscape LX2160A has an almost compatible controller, with a few
quirks:
 - IBCR bit 7 is "module disable" instead of "module enable".
 - Status bits in IBSR are W1C.
Add quirk flags for both.


(jmcneill)
diff -r1.9 -r1.10 src/sys/dev/i2c/motoi2c.c
diff -r1.7 -r1.8 src/sys/dev/i2c/motoi2cvar.h

cvs diff -r1.9 -r1.10 src/sys/dev/i2c/motoi2c.c (expand / switch to unified diff)

--- src/sys/dev/i2c/motoi2c.c 2021/01/24 18:01:13 1.9
+++ src/sys/dev/i2c/motoi2c.c 2021/01/25 12:08:47 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: motoi2c.c,v 1.9 2021/01/24 18:01:13 jmcneill Exp $ */ 1/* $NetBSD: motoi2c.c,v 1.10 2021/01/25 12:08:47 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas. 8 * by Matt Thomas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: motoi2c.c,v 1.9 2021/01/24 18:01:13 jmcneill Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: motoi2c.c,v 1.10 2021/01/25 12:08:47 jmcneill Exp $");
34 34
35#if defined(__arm__) || defined(__aarch64__) 35#if defined(__arm__) || defined(__aarch64__)
36#include "opt_fdt.h" 36#include "opt_fdt.h"
37#endif 37#endif
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/systm.h> 41#include <sys/systm.h>
42#include <sys/mutex.h> 42#include <sys/mutex.h>
43#include <sys/bus.h> 43#include <sys/bus.h>
44#include <sys/intr.h> 44#include <sys/intr.h>
45 45
46#include <dev/i2c/i2cvar.h> 46#include <dev/i2c/i2cvar.h>
@@ -99,104 +99,126 @@ motoi2c_attach_common(device_t self, str @@ -99,104 +99,126 @@ motoi2c_attach_common(device_t self, str
99 iic_tag_init(&sc->sc_i2c); 99 iic_tag_init(&sc->sc_i2c);
100 sc->sc_i2c.ic_cookie = sc; 100 sc->sc_i2c.ic_cookie = sc;
101 sc->sc_i2c.ic_acquire_bus = motoi2c_acquire_bus; 101 sc->sc_i2c.ic_acquire_bus = motoi2c_acquire_bus;
102 sc->sc_i2c.ic_release_bus = motoi2c_release_bus; 102 sc->sc_i2c.ic_release_bus = motoi2c_release_bus;
103 sc->sc_i2c.ic_exec = motoi2c_exec; 103 sc->sc_i2c.ic_exec = motoi2c_exec;
104 if (sc->sc_iord == NULL) 104 if (sc->sc_iord == NULL)
105 sc->sc_iord = motoi2c_iord1; 105 sc->sc_iord = motoi2c_iord1;
106 if (sc->sc_iowr == NULL) 106 if (sc->sc_iowr == NULL)
107 sc->sc_iowr = motoi2c_iowr1; 107 sc->sc_iowr = motoi2c_iowr1;
108 memset(&iba, 0, sizeof(iba)); 108 memset(&iba, 0, sizeof(iba));
109 iba.iba_tag = &sc->sc_i2c; 109 iba.iba_tag = &sc->sc_i2c;
110 iba.iba_child_devices = sc->sc_child_devices; 110 iba.iba_child_devices = sc->sc_child_devices;
111 111
112 I2C_WRITE(I2CCR, 0); /* reset before changing anything */ 112 if ((sc->sc_flags & MOTOI2C_F_ENABLE_INV) != 0) {
 113 sc->sc_enable_mask = 0;
 114 sc->sc_disable_mask = CR_MEN;
 115 } else {
 116 sc->sc_enable_mask = CR_MEN;
 117 sc->sc_disable_mask = 0;
 118 }
 119
 120 I2C_WRITE(I2CCR, sc->sc_disable_mask); /* reset before config */
113 I2C_WRITE(I2CDFSRR, i2c->i2c_dfsrr); /* sampling units */ 121 I2C_WRITE(I2CDFSRR, i2c->i2c_dfsrr); /* sampling units */
114 I2C_WRITE(I2CFDR, i2c->i2c_fdr); /* divider 3072 (0x31) */ 122 I2C_WRITE(I2CFDR, i2c->i2c_fdr); /* divider 3072 (0x31) */
115 I2C_WRITE(I2CADR, i2c->i2c_adr); /* our slave address is 0x7f */ 123 I2C_WRITE(I2CADR, i2c->i2c_adr); /* our slave address is 0x7f */
116 I2C_WRITE(I2CSR, 0); /* clear status flags */ 124 if ((sc->sc_flags & MOTOI2C_F_STATUS_W1C) != 0) {
 125 I2C_WRITE(I2CSR, I2C_READ(I2CSR)); /* clear status flags */
 126 } else {
 127 I2C_WRITE(I2CSR, 0); /* clear status flags */
 128 }
117 129
118#ifdef FDT 130#ifdef FDT
119 if (sc->sc_phandle != 0) { 131 if (sc->sc_phandle != 0) {
120 fdtbus_register_i2c_controller(&sc->sc_i2c, sc->sc_phandle); 132 fdtbus_register_i2c_controller(&sc->sc_i2c, sc->sc_phandle);
121 fdtbus_attach_i2cbus(self, sc->sc_phandle, &sc->sc_i2c, 133 fdtbus_attach_i2cbus(self, sc->sc_phandle, &sc->sc_i2c,
122 iicbus_print); 134 iicbus_print);
123 } else 135 } else
124#endif 136#endif
125 config_found_ia(self, "i2cbus", &iba, iicbus_print); 137 config_found_ia(self, "i2cbus", &iba, iicbus_print);
126} 138}
127 139
128static int 140static int
129motoi2c_acquire_bus(void *v, int flags) 141motoi2c_acquire_bus(void *v, int flags)
130{ 142{
131 struct motoi2c_softc * const sc = v; 143 struct motoi2c_softc * const sc = v;
132 144
133 I2C_WRITE(I2CCR, CR_MEN); /* enable the I2C module */ 145 I2C_WRITE(I2CCR, sc->sc_enable_mask); /* enable the I2C module */
134 146
135 return 0; 147 return 0;
136} 148}
137 149
138static void 150static void
139motoi2c_release_bus(void *v, int flags) 151motoi2c_release_bus(void *v, int flags)
140{ 152{
141 struct motoi2c_softc * const sc = v; 153 struct motoi2c_softc * const sc = v;
142 154
143 I2C_WRITE(I2CCR, 0); /* reset before changing anything */ 155 I2C_WRITE(I2CCR, sc->sc_disable_mask); /* disable the I2C module */
144} 156}
145 157
146static int 158static int
147motoi2c_stop_wait(struct motoi2c_softc *sc) 159motoi2c_stop_wait(struct motoi2c_softc *sc)
148{ 160{
149 u_int timo; 161 u_int timo;
150 int error = 0; 162 int error = 0;
151 163
152 timo = 1000; 164 timo = 1000;
153 while ((I2C_READ(I2CSR) & SR_MBB) != 0 && --timo) 165 while ((I2C_READ(I2CSR) & SR_MBB) != 0 && --timo)
154 DELAY(1); 166 DELAY(1);
155 167
156 if (timo == 0) { 168 if (timo == 0) {
157 DPRINTF(("%s: timeout (sr=%#x)\n", __func__, I2C_READ(I2CSR))); 169 DPRINTF(("%s: timeout (sr=%#x)\n", __func__, I2C_READ(I2CSR)));
158 error = ETIMEDOUT; 170 error = ETIMEDOUT;
159 } 171 }
160 172
161 return error; 173 return error;
162} 174}
163 175
 176static void
 177motoi2c_clear_status(struct motoi2c_softc *sc, uint8_t sr)
 178{
 179 if ((sc->sc_flags & MOTOI2C_F_STATUS_W1C) != 0) {
 180 I2C_WRITE(I2CSR, sr);
 181 } else {
 182 I2C_WRITE(I2CSR, 0);
 183 }
 184}
 185
164/* busy waiting for byte data transfer completion */ 186/* busy waiting for byte data transfer completion */
165static int 187static int
166motoi2c_busy_wait(struct motoi2c_softc *sc, uint8_t cr) 188motoi2c_busy_wait(struct motoi2c_softc *sc, uint8_t cr)
167{ 189{
168 uint8_t sr; 190 uint8_t sr;
169 u_int timo; 191 u_int timo;
170 int error = 0; 192 int error = 0;
171 193
172 timo = 1000; 194 timo = 1000;
173 while (((sr = I2C_READ(I2CSR)) & SR_MIF) == 0 && --timo) 195 while (((sr = I2C_READ(I2CSR)) & SR_MIF) == 0 && --timo)
174 DELAY(10); 196 DELAY(10);
175 197
176 if (timo == 0) { 198 if (timo == 0) {
177 DPRINTF(("%s: timeout (sr=%#x, cr=%#x)\n", 199 DPRINTF(("%s: timeout (sr=%#x, cr=%#x)\n",
178 __func__, sr, I2C_READ(I2CCR))); 200 __func__, sr, I2C_READ(I2CCR)));
179 error = ETIMEDOUT; 201 error = ETIMEDOUT;
180 } 202 }
181 /* 203 /*
182 * RXAK is only valid when transmitting. 204 * RXAK is only valid when transmitting.
183 */ 205 */
184 if ((cr & CR_MTX) && (sr & SR_RXAK)) { 206 if ((cr & CR_MTX) && (sr & SR_RXAK)) {
185 DPRINTF(("%s: missing rx ack (%#x): spin=%u\n", 207 DPRINTF(("%s: missing rx ack (%#x): spin=%u\n",
186 __func__, sr, 1000 - timo)); 208 __func__, sr, 1000 - timo));
187 error = EIO; 209 error = EIO;
188 } 210 }
189 I2C_WRITE(I2CSR, 0); 211 motoi2c_clear_status(sc, sr);
190 return error; 212 return error;
191} 213}
192 214
193int 215int
194motoi2c_intr(void *v) 216motoi2c_intr(void *v)
195{ 217{
196 struct motoi2c_softc * const sc = v; 218 struct motoi2c_softc * const sc = v;
197 219
198 panic("%s(%p)", __func__, sc); 220 panic("%s(%p)", __func__, sc);
199 221
200 return 0; 222 return 0;
201} 223}
202 224
@@ -218,45 +240,45 @@ motoi2c_exec(void *v, i2c_op_t op, i2c_a @@ -218,45 +240,45 @@ motoi2c_exec(void *v, i2c_op_t op, i2c_a
218 DPRINTF(("%s(%#x,%#x,%p,%zu,%p,%zu,%#x): sr=%#x cr=%#x\n", 240 DPRINTF(("%s(%#x,%#x,%p,%zu,%p,%zu,%#x): sr=%#x cr=%#x\n",
219 __func__, op, addr, cmdbuf, cmdlen, databuf, datalen, flags, 241 __func__, op, addr, cmdbuf, cmdlen, databuf, datalen, flags,
220 sr, cr)); 242 sr, cr));
221#endif 243#endif
222 244
223 if ((cr & CR_MSTA) == 0 && (sr & SR_MBB) != 0) { 245 if ((cr & CR_MSTA) == 0 && (sr & SR_MBB) != 0) {
224 /* wait for bus becoming available */ 246 /* wait for bus becoming available */
225 error = motoi2c_stop_wait(sc); 247 error = motoi2c_stop_wait(sc);
226 if (error) 248 if (error)
227 return ETIMEDOUT; 249 return ETIMEDOUT;
228 } 250 }
229 251
230 /* reset interrupt and arbitration-lost flags (all others are RO) */ 252 /* reset interrupt and arbitration-lost flags (all others are RO) */
231 I2C_WRITE(I2CSR, 0); 253 motoi2c_clear_status(sc, sr);
232 sr = I2C_READ(I2CSR); 254 sr = I2C_READ(I2CSR);
233 255
234 /* 256 /*
235 * Generate start condition 257 * Generate start condition
236 */ 258 */
237 cr = CR_MEN | CR_MTX | CR_MSTA; 259 cr = sc->sc_enable_mask | CR_MTX | CR_MSTA;
238 I2C_WRITE(I2CCR, cr); 260 I2C_WRITE(I2CCR, cr);
239 261
240 DPRINTF(("%s: started: sr=%#x cr=%#x/%#x\n", 262 DPRINTF(("%s: started: sr=%#x cr=%#x/%#x\n",
241 __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR))); 263 __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));
242 264
243 sr = I2C_READ(I2CSR); 265 sr = I2C_READ(I2CSR);
244 if (sr & SR_MAL) { 266 if (sr & SR_MAL) {
245 DPRINTF(("%s: lost bus: sr=%#x cr=%#x/%#x\n", 267 DPRINTF(("%s: lost bus: sr=%#x cr=%#x/%#x\n",
246 __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR))); 268 __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));
247 I2C_WRITE(I2CCR, 0); 269 I2C_WRITE(I2CCR, sc->sc_disable_mask);
248 DELAY(10); 270 DELAY(10);
249 I2C_WRITE(I2CCR, CR_MEN | CR_MTX | CR_MSTA); 271 I2C_WRITE(I2CCR, sc->sc_enable_mask | CR_MTX | CR_MSTA);
250 DELAY(10); 272 DELAY(10);
251 sr = I2C_READ(I2CSR); 273 sr = I2C_READ(I2CSR);
252 if (sr & SR_MAL) { 274 if (sr & SR_MAL) {
253 error = EBUSY; 275 error = EBUSY;
254 goto out; 276 goto out;
255 } 277 }
256 DPRINTF(("%s: reacquired bus: sr=%#x cr=%#x/%#x\n", 278 DPRINTF(("%s: reacquired bus: sr=%#x cr=%#x/%#x\n",
257 __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR))); 279 __func__, I2C_READ(I2CSR), cr, I2C_READ(I2CCR)));
258 } 280 }
259 281
260 /* send target address and transfer direction */ 282 /* send target address and transfer direction */
261 uint8_t addr_byte = (addr << 1) 283 uint8_t addr_byte = (addr << 1)
262 | (cmdlen == 0 && I2C_OP_READ_P(op) ? 1 : 0); 284 | (cmdlen == 0 && I2C_OP_READ_P(op) ? 1 : 0);
@@ -319,34 +341,34 @@ motoi2c_exec(void *v, i2c_op_t op, i2c_a @@ -319,34 +341,34 @@ motoi2c_exec(void *v, i2c_op_t op, i2c_a
319 * the transmit acknowledge bit (I2CCR[TXAK])) before 341 * the transmit acknowledge bit (I2CCR[TXAK])) before
320 * reading the next-to-last byte of data.  342 * reading the next-to-last byte of data.
321 */ 343 */
322 error = motoi2c_busy_wait(sc, cr); 344 error = motoi2c_busy_wait(sc, cr);
323 if (error) { 345 if (error) {
324 DPRINTF(("%s: error reading byte %zu: %d\n", 346 DPRINTF(("%s: error reading byte %zu: %d\n",
325 __func__, i, error)); 347 __func__, i, error));
326 goto out; 348 goto out;
327 } 349 }
328 if (i == datalen - 2) { 350 if (i == datalen - 2) {
329 cr |= CR_TXAK; 351 cr |= CR_TXAK;
330 I2C_WRITE(I2CCR, cr); 352 I2C_WRITE(I2CCR, cr);
331 } else if (i == datalen - 1 && I2C_OP_STOP_P(op)) { 353 } else if (i == datalen - 1 && I2C_OP_STOP_P(op)) {
332 cr = CR_MEN | CR_TXAK; 354 cr = sc->sc_enable_mask | CR_TXAK;
333 I2C_WRITE(I2CCR, cr); 355 I2C_WRITE(I2CCR, cr);
334 } 356 }
335 *dataptr++ = I2C_READ(I2CDR); 357 *dataptr++ = I2C_READ(I2CDR);
336 } 358 }
337 if (datalen == 0) { 359 if (datalen == 0) {
338 if (I2C_OP_STOP_P(op)) { 360 if (I2C_OP_STOP_P(op)) {
339 cr = CR_MEN | CR_TXAK; 361 cr = sc->sc_enable_mask | CR_TXAK;
340 I2C_WRITE(I2CCR, cr); 362 I2C_WRITE(I2CCR, cr);
341 } 363 }
342 (void)I2C_READ(I2CDR); /* dummy read */ 364 (void)I2C_READ(I2CDR); /* dummy read */
343 error = motoi2c_busy_wait(sc, cr); 365 error = motoi2c_busy_wait(sc, cr);
344 if (error) { 366 if (error) {
345 DPRINTF(("%s: error reading dummy last byte:" 367 DPRINTF(("%s: error reading dummy last byte:"
346 "%d\n", __func__, error)); 368 "%d\n", __func__, error));
347 goto out; 369 goto out;
348 } 370 }
349 } 371 }
350 } else { 372 } else {
351 const uint8_t *dataptr = databuf; 373 const uint8_t *dataptr = databuf;
352 for (size_t i = 0; i < datalen; i++) { 374 for (size_t i = 0; i < datalen; i++) {
@@ -356,25 +378,25 @@ motoi2c_exec(void *v, i2c_op_t op, i2c_a @@ -356,25 +378,25 @@ motoi2c_exec(void *v, i2c_op_t op, i2c_a
356 DPRINTF(("%s: error sending data byte %zu:" 378 DPRINTF(("%s: error sending data byte %zu:"
357 " %d\n", __func__, i, error)); 379 " %d\n", __func__, i, error));
358 goto out; 380 goto out;
359 } 381 }
360 } 382 }
361 } 383 }
362 384
363 out: 385 out:
364 /* 386 /*
365 * If we encountered an error condition or caller wants a STOP, 387 * If we encountered an error condition or caller wants a STOP,
366 * send a STOP. 388 * send a STOP.
367 */ 389 */
368 if (error || (cr & CR_TXAK) || ((cr & CR_MSTA) && I2C_OP_STOP_P(op))) { 390 if (error || (cr & CR_TXAK) || ((cr & CR_MSTA) && I2C_OP_STOP_P(op))) {
369 cr = CR_MEN; 391 cr = sc->sc_enable_mask;
370 I2C_WRITE(I2CCR, cr); 392 I2C_WRITE(I2CCR, cr);
371 motoi2c_stop_wait(sc); 393 motoi2c_stop_wait(sc);
372 DPRINTF(("%s: stopping: cr=%#x/%#x\n", __func__, 394 DPRINTF(("%s: stopping: cr=%#x/%#x\n", __func__,
373 cr, I2C_READ(I2CCR))); 395 cr, I2C_READ(I2CCR)));
374 } 396 }
375 397
376 DPRINTF(("%s: exit sr=%#x cr=%#x: %d\n", __func__, 398 DPRINTF(("%s: exit sr=%#x cr=%#x: %d\n", __func__,
377 I2C_READ(I2CSR), I2C_READ(I2CCR), error)); 399 I2C_READ(I2CSR), I2C_READ(I2CCR), error));
378 400
379 return error; 401 return error;
380} 402}

cvs diff -r1.7 -r1.8 src/sys/dev/i2c/motoi2cvar.h (expand / switch to unified diff)

--- src/sys/dev/i2c/motoi2cvar.h 2021/01/24 18:01:13 1.7
+++ src/sys/dev/i2c/motoi2cvar.h 2021/01/25 12:08:47 1.8
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: motoi2cvar.h,v 1.7 2021/01/24 18:01:13 jmcneill Exp $ */ 1/* $NetBSD: motoi2cvar.h,v 1.8 2021/01/25 12:08:47 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 2007, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Matt Thomas. 8 * by Matt Thomas.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -42,26 +42,31 @@ struct motoi2c_settings { @@ -42,26 +42,31 @@ struct motoi2c_settings {
42 uint8_t i2c_adr; 42 uint8_t i2c_adr;
43 uint8_t i2c_fdr; 43 uint8_t i2c_fdr;
44 uint8_t i2c_dfsrr; 44 uint8_t i2c_dfsrr;
45}; 45};
46 46
47struct motoi2c_softc { 47struct motoi2c_softc {
48 bus_space_tag_t sc_iot; 48 bus_space_tag_t sc_iot;
49 bus_space_handle_t sc_ioh; 49 bus_space_handle_t sc_ioh;
50 struct i2c_controller sc_i2c; 50 struct i2c_controller sc_i2c;
51 motoi2c_iord_t sc_iord; 51 motoi2c_iord_t sc_iord;
52 motoi2c_iowr_t sc_iowr; 52 motoi2c_iowr_t sc_iowr;
53 int sc_phandle; 53 int sc_phandle;
54 prop_array_t sc_child_devices; 54 prop_array_t sc_child_devices;
 55 int sc_flags;
 56#define MOTOI2C_F_ENABLE_INV __BIT(0)
 57#define MOTOI2C_F_STATUS_W1C __BIT(1)
 58 uint8_t sc_enable_mask;
 59 uint8_t sc_disable_mask;
55}; 60};
56 61
57#define MOTOI2C_ADR_DEFAULT (0x7e << 1) 62#define MOTOI2C_ADR_DEFAULT (0x7e << 1)
58#define MOTOI2C_FDR_DEFAULT 0x31 /* 3072 */ 63#define MOTOI2C_FDR_DEFAULT 0x31 /* 3072 */
59#define MOTOI2C_DFSRR_DEFAULT 0x10 64#define MOTOI2C_DFSRR_DEFAULT 0x10
60 65
61#ifdef _KERNEL 66#ifdef _KERNEL
62void motoi2c_attach_common(device_t, struct motoi2c_softc *, 67void motoi2c_attach_common(device_t, struct motoi2c_softc *,
63 const struct motoi2c_settings *); 68 const struct motoi2c_settings *);
64int motoi2c_intr(void *); 69int motoi2c_intr(void *);
65#endif 70#endif
66 71
67#endif /* !_DEV_I2C_MOTOI2CVAR_H_ */ 72#endif /* !_DEV_I2C_MOTOI2CVAR_H_ */