ki2c.c revision 1.31.2.1 1 1.31.2.1 thorpej /* $NetBSD: ki2c.c,v 1.31.2.1 2021/05/08 21:58:12 thorpej Exp $ */
2 1.1 grant /* Id: ki2c.c,v 1.7 2002/10/05 09:56:05 tsubai Exp */
3 1.1 grant
4 1.1 grant /*-
5 1.1 grant * Copyright (c) 2001 Tsubai Masanari. All rights reserved.
6 1.1 grant *
7 1.1 grant * Redistribution and use in source and binary forms, with or without
8 1.1 grant * modification, are permitted provided that the following conditions
9 1.1 grant * are met:
10 1.1 grant * 1. Redistributions of source code must retain the above copyright
11 1.1 grant * notice, this list of conditions and the following disclaimer.
12 1.1 grant * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 grant * notice, this list of conditions and the following disclaimer in the
14 1.1 grant * documentation and/or other materials provided with the distribution.
15 1.1 grant * 3. The name of the author may not be used to endorse or promote products
16 1.1 grant * derived from this software without specific prior written permission.
17 1.1 grant *
18 1.1 grant * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 1.1 grant * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 1.1 grant * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 1.1 grant * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 1.1 grant * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 1.1 grant * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 1.1 grant * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 1.1 grant * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 1.1 grant * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 1.1 grant * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 1.1 grant */
29 1.1 grant
30 1.1 grant #include <sys/param.h>
31 1.1 grant #include <sys/device.h>
32 1.1 grant #include <sys/systm.h>
33 1.31.2.1 thorpej #include <sys/kmem.h>
34 1.11 ad #include <sys/mutex.h>
35 1.1 grant
36 1.1 grant #include <dev/ofw/openfirm.h>
37 1.1 grant #include <machine/autoconf.h>
38 1.1 grant
39 1.29 macallan #include "opt_ki2c.h"
40 1.3 macallan #include <macppc/dev/ki2cvar.h>
41 1.1 grant
42 1.31.2.1 thorpej #include "locators.h"
43 1.31.2.1 thorpej
44 1.20 macallan #ifdef KI2C_DEBUG
45 1.20 macallan #define DPRINTF printf
46 1.20 macallan #else
47 1.20 macallan #define DPRINTF while (0) printf
48 1.20 macallan #endif
49 1.20 macallan
50 1.31.2.1 thorpej static int ki2c_match(device_t, cfdata_t, void *);
51 1.31.2.1 thorpej static void ki2c_attach(device_t, device_t, void *);
52 1.31.2.1 thorpej static int ki2c_intr(struct ki2c_softc *);
53 1.3 macallan
54 1.3 macallan /* I2C glue */
55 1.31.2.1 thorpej static int ki2c_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
56 1.31.2.1 thorpej size_t, void *, size_t, int);
57 1.31.2.1 thorpej static int ki2c_i2c_acquire_bus(void *, int);
58 1.31.2.1 thorpej static void ki2c_i2c_release_bus(void *, int);
59 1.1 grant
60 1.18 macallan CFATTACH_DECL_NEW(ki2c, sizeof(struct ki2c_softc), ki2c_match, ki2c_attach,
61 1.9 dogcow NULL, NULL);
62 1.1 grant
63 1.31.2.1 thorpej static prop_dictionary_t
64 1.31.2.1 thorpej ki2c_i2c_device_props(struct ki2c_softc *sc, int node)
65 1.31.2.1 thorpej {
66 1.31.2.1 thorpej prop_dictionary_t props = prop_dictionary_create();
67 1.31.2.1 thorpej uint32_t reg;
68 1.31.2.1 thorpej char descr[32], num[8];
69 1.31.2.1 thorpej
70 1.31.2.1 thorpej /* We're fetching descriptions for sensors. */
71 1.31.2.1 thorpej
72 1.31.2.1 thorpej for (node = OF_child(node); node != 0; node = OF_peer(node)) {
73 1.31.2.1 thorpej if (of_getprop_uint32(node, "reg", ®) == -1) {
74 1.31.2.1 thorpej continue;
75 1.31.2.1 thorpej }
76 1.31.2.1 thorpej if (OF_getprop(node, "location", descr, sizeof(descr)) <= 0) {
77 1.31.2.1 thorpej continue;
78 1.31.2.1 thorpej }
79 1.31.2.1 thorpej snprintf(num, sizeof(num), "s%02x", reg);
80 1.31.2.1 thorpej
81 1.31.2.1 thorpej aprint_debug_dev(sc->sc_dev,
82 1.31.2.1 thorpej "%s: sensor %s -> %s\n", __func__, num, descr);
83 1.31.2.1 thorpej
84 1.31.2.1 thorpej prop_dictionary_set_string(props, num, descr);
85 1.31.2.1 thorpej }
86 1.31.2.1 thorpej
87 1.31.2.1 thorpej return props;
88 1.31.2.1 thorpej }
89 1.31.2.1 thorpej
90 1.31.2.1 thorpej static bool
91 1.31.2.1 thorpej ki2c_i2c_enumerate_device(struct ki2c_softc *sc, device_t dev, int node,
92 1.31.2.1 thorpej const char *name, uint32_t addr,
93 1.31.2.1 thorpej struct i2c_enumerate_devices_args * const args)
94 1.31.2.1 thorpej {
95 1.31.2.1 thorpej int compat_size;
96 1.31.2.1 thorpej prop_dictionary_t props;
97 1.31.2.1 thorpej char compat_buf[32];
98 1.31.2.1 thorpej char *compat;
99 1.31.2.1 thorpej bool cbrv;
100 1.31.2.1 thorpej
101 1.31.2.1 thorpej compat_size = OF_getproplen(node, "compatible");
102 1.31.2.1 thorpej if (compat_size <= 0) {
103 1.31.2.1 thorpej /* some i2c device nodes don't have 'compatible' */
104 1.31.2.1 thorpej aprint_debug_dev(sc->sc_dev,
105 1.31.2.1 thorpej "no compatible property for phandle %d; using '%s'\n",
106 1.31.2.1 thorpej node, name);
107 1.31.2.1 thorpej compat = compat_buf;
108 1.31.2.1 thorpej strlcpy(compat, name, sizeof(compat));
109 1.31.2.1 thorpej compat_size = strlen(compat) + 1;
110 1.31.2.1 thorpej } else {
111 1.31.2.1 thorpej compat = kmem_tmpbuf_alloc(compat_size, compat_buf,
112 1.31.2.1 thorpej sizeof(compat_buf), KM_SLEEP);
113 1.31.2.1 thorpej if (OF_getprop(node, "compatible", compat,
114 1.31.2.1 thorpej sizeof(compat)) <= 0) {
115 1.31.2.1 thorpej aprint_error_dev(sc->sc_dev,
116 1.31.2.1 thorpej "unable to get compatible property for "
117 1.31.2.1 thorpej "phandle %d ('%s')\n", node, name);
118 1.31.2.1 thorpej goto bad;
119 1.31.2.1 thorpej }
120 1.31.2.1 thorpej }
121 1.31.2.1 thorpej
122 1.31.2.1 thorpej props = ki2c_i2c_device_props(sc, node);
123 1.31.2.1 thorpej
124 1.31.2.1 thorpej args->ia->ia_addr = (i2c_addr_t)addr;
125 1.31.2.1 thorpej args->ia->ia_name = name;
126 1.31.2.1 thorpej args->ia->ia_clist = compat;
127 1.31.2.1 thorpej args->ia->ia_clist_size = compat_size;
128 1.31.2.1 thorpej args->ia->ia_prop = props;
129 1.31.2.1 thorpej args->ia->ia_devhandle = devhandle_from_of(node);
130 1.31.2.1 thorpej
131 1.31.2.1 thorpej cbrv = args->callback(dev, args);
132 1.31.2.1 thorpej
133 1.31.2.1 thorpej prop_object_release(props);
134 1.31.2.1 thorpej
135 1.31.2.1 thorpej return cbrv; /* callback decides if we keep enumerating */
136 1.31.2.1 thorpej
137 1.31.2.1 thorpej bad:
138 1.31.2.1 thorpej if (compat != compat_buf) {
139 1.31.2.1 thorpej kmem_tmpbuf_free(compat, compat_size, compat_buf);
140 1.31.2.1 thorpej }
141 1.31.2.1 thorpej return true; /* keep enumerating */
142 1.31.2.1 thorpej }
143 1.31.2.1 thorpej
144 1.31.2.1 thorpej static int
145 1.31.2.1 thorpej ki2c_i2c_enumerate_devices(device_t dev, devhandle_t call_handle, void *v)
146 1.31.2.1 thorpej {
147 1.31.2.1 thorpej struct i2c_enumerate_devices_args *args = v;
148 1.31.2.1 thorpej int bus_phandle, node;
149 1.31.2.1 thorpej uint32_t addr;
150 1.31.2.1 thorpej char name[32];
151 1.31.2.1 thorpej
152 1.31.2.1 thorpej /* dev is the "iic" bus instance. ki2c channel is in args. */
153 1.31.2.1 thorpej struct ki2c_channel *ch = args->ia->ia_tag->ic_cookie;
154 1.31.2.1 thorpej struct ki2c_softc *sc = ch->ch_ki2c;
155 1.31.2.1 thorpej
156 1.31.2.1 thorpej /*
157 1.31.2.1 thorpej * If we're not using the separate nodes scheme, we need
158 1.31.2.1 thorpej * to filter out devices from the other channel. We detect
159 1.31.2.1 thorpej * this by comparing the bus phandle to the controller phandle,
160 1.31.2.1 thorpej * and if they match, we are NOT using the separate nodes
161 1.31.2.1 thorpej * scheme.
162 1.31.2.1 thorpej */
163 1.31.2.1 thorpej bus_phandle = devhandle_to_of(device_handle(dev));
164 1.31.2.1 thorpej bool filter_by_channel =
165 1.31.2.1 thorpej bus_phandle == devhandle_to_of(device_handle(sc->sc_dev));
166 1.31.2.1 thorpej
167 1.31.2.1 thorpej for (node = OF_child(bus_phandle); node != 0; node = OF_peer(node)) {
168 1.31.2.1 thorpej if (OF_getprop(node, "name", name, sizeof(name)) <= 0) {
169 1.31.2.1 thorpej aprint_error_dev(sc->sc_dev,
170 1.31.2.1 thorpej "unable to get name property for phandle %d\n",
171 1.31.2.1 thorpej node);
172 1.31.2.1 thorpej continue;
173 1.31.2.1 thorpej }
174 1.31.2.1 thorpej if (of_getprop_uint32(node, "reg", &addr) == -1 &&
175 1.31.2.1 thorpej of_getprop_uint32(node, "i2c-address", &addr) == -1) {
176 1.31.2.1 thorpej aprint_error_dev(sc->sc_dev,
177 1.31.2.1 thorpej "unable to get i2c address for phandle %d ('%s')\n",
178 1.31.2.1 thorpej node, name);
179 1.31.2.1 thorpej continue;
180 1.31.2.1 thorpej }
181 1.31.2.1 thorpej if (filter_by_channel && ((addr >> 8) & 1) != ch->ch_channel) {
182 1.31.2.1 thorpej continue;
183 1.31.2.1 thorpej }
184 1.31.2.1 thorpej addr = (addr & 0xff) >> 1;
185 1.31.2.1 thorpej if (!ki2c_i2c_enumerate_device(sc, dev, node, name, addr,
186 1.31.2.1 thorpej args)) {
187 1.31.2.1 thorpej break;
188 1.31.2.1 thorpej }
189 1.31.2.1 thorpej }
190 1.31.2.1 thorpej
191 1.31.2.1 thorpej return 0;
192 1.31.2.1 thorpej }
193 1.31.2.1 thorpej
194 1.31.2.1 thorpej static device_call_t
195 1.31.2.1 thorpej ki2c_devhandle_lookup_device_call(devhandle_t handle, const char *name,
196 1.31.2.1 thorpej devhandle_t *call_handlep)
197 1.31.2.1 thorpej {
198 1.31.2.1 thorpej if (strcmp(name, "i2c-enumerate-devices") == 0) {
199 1.31.2.1 thorpej return ki2c_i2c_enumerate_devices;
200 1.31.2.1 thorpej }
201 1.31.2.1 thorpej
202 1.31.2.1 thorpej /* Defer everything else to the "super". */
203 1.31.2.1 thorpej return NULL;
204 1.31.2.1 thorpej }
205 1.31.2.1 thorpej
206 1.31.2.1 thorpej static inline uint8_t
207 1.31.2.1 thorpej ki2c_readreg(struct ki2c_softc *sc, int reg)
208 1.31.2.1 thorpej {
209 1.31.2.1 thorpej
210 1.31.2.1 thorpej return bus_space_read_1(sc->sc_tag, sc->sc_bh, sc->sc_regstep * reg);
211 1.31.2.1 thorpej }
212 1.31.2.1 thorpej
213 1.31.2.1 thorpej static inline void
214 1.31.2.1 thorpej ki2c_writereg(struct ki2c_softc *sc, int reg, uint8_t val)
215 1.31.2.1 thorpej {
216 1.31.2.1 thorpej
217 1.31.2.1 thorpej bus_space_write_1(sc->sc_tag, sc->sc_bh, reg * sc->sc_regstep, val);
218 1.31.2.1 thorpej delay(10);
219 1.31.2.1 thorpej }
220 1.31.2.1 thorpej
221 1.31.2.1 thorpej #if 0
222 1.31.2.1 thorpej static u_int
223 1.31.2.1 thorpej ki2c_getmode(struct ki2c_softc *sc)
224 1.31.2.1 thorpej {
225 1.31.2.1 thorpej return ki2c_readreg(sc, MODE) & I2C_MODE;
226 1.31.2.1 thorpej }
227 1.31.2.1 thorpej #endif
228 1.31.2.1 thorpej
229 1.31.2.1 thorpej static void
230 1.31.2.1 thorpej ki2c_setmode(struct ki2c_softc *sc, u_int mode)
231 1.31.2.1 thorpej {
232 1.31.2.1 thorpej ki2c_writereg(sc, MODE, mode);
233 1.31.2.1 thorpej }
234 1.31.2.1 thorpej
235 1.31.2.1 thorpej #if 0
236 1.31.2.1 thorpej static u_int
237 1.31.2.1 thorpej ki2c_getspeed(struct ki2c_softc *sc)
238 1.31.2.1 thorpej {
239 1.31.2.1 thorpej return ki2c_readreg(sc, MODE) & I2C_SPEED;
240 1.31.2.1 thorpej }
241 1.31.2.1 thorpej #endif
242 1.31.2.1 thorpej
243 1.31.2.1 thorpej static void
244 1.31.2.1 thorpej ki2c_setspeed(struct ki2c_softc *sc, u_int speed)
245 1.31.2.1 thorpej {
246 1.31.2.1 thorpej u_int x;
247 1.31.2.1 thorpej
248 1.31.2.1 thorpej KASSERT((speed & ~I2C_SPEED) == 0);
249 1.31.2.1 thorpej x = ki2c_readreg(sc, MODE);
250 1.31.2.1 thorpej x &= ~I2C_SPEED;
251 1.31.2.1 thorpej x |= speed;
252 1.31.2.1 thorpej ki2c_writereg(sc, MODE, x);
253 1.31.2.1 thorpej }
254 1.31.2.1 thorpej
255 1.31.2.1 thorpej static int
256 1.17 matt ki2c_match(device_t parent, cfdata_t match, void *aux)
257 1.1 grant {
258 1.1 grant struct confargs *ca = aux;
259 1.1 grant
260 1.1 grant if (strcmp(ca->ca_name, "i2c") == 0)
261 1.1 grant return 1;
262 1.1 grant
263 1.1 grant return 0;
264 1.1 grant }
265 1.1 grant
266 1.31.2.1 thorpej static void
267 1.17 matt ki2c_attach(device_t parent, device_t self, void *aux)
268 1.1 grant {
269 1.17 matt struct ki2c_softc *sc = device_private(self);
270 1.1 grant struct confargs *ca = aux;
271 1.31.2.1 thorpej struct ki2c_channel *ch;
272 1.1 grant int node = ca->ca_node;
273 1.31.2.1 thorpej uint32_t channel, addr;
274 1.31.2.1 thorpej int i, rate, child;
275 1.3 macallan struct i2cbus_attach_args iba;
276 1.31.2.1 thorpej devhandle_t devhandle;
277 1.3 macallan char name[32];
278 1.18 macallan
279 1.18 macallan sc->sc_dev = self;
280 1.21 macallan sc->sc_tag = ca->ca_tag;
281 1.1 grant ca->ca_reg[0] += ca->ca_baseaddr;
282 1.1 grant
283 1.1 grant if (OF_getprop(node, "AAPL,i2c-rate", &rate, 4) != 4) {
284 1.20 macallan aprint_error(": cannot get i2c-rate\n");
285 1.1 grant return;
286 1.1 grant }
287 1.20 macallan if (OF_getprop(node, "AAPL,address", &addr, 4) != 4) {
288 1.20 macallan aprint_error(": unable to find i2c address\n");
289 1.1 grant return;
290 1.1 grant }
291 1.21 macallan if (bus_space_map(sc->sc_tag, addr, PAGE_SIZE, 0, &sc->sc_bh) != 0) {
292 1.21 macallan aprint_error_dev(sc->sc_dev, "failed to map registers\n");
293 1.21 macallan return;
294 1.21 macallan }
295 1.21 macallan
296 1.1 grant if (OF_getprop(node, "AAPL,address-step", &sc->sc_regstep, 4) != 4) {
297 1.20 macallan aprint_error(": unable to find i2c address step\n");
298 1.1 grant return;
299 1.1 grant }
300 1.1 grant
301 1.1 grant printf("\n");
302 1.1 grant
303 1.1 grant ki2c_writereg(sc, STATUS, 0);
304 1.1 grant ki2c_writereg(sc, ISR, 0);
305 1.1 grant ki2c_writereg(sc, IER, 0);
306 1.1 grant
307 1.1 grant ki2c_setmode(sc, I2C_STDSUBMODE);
308 1.1 grant ki2c_setspeed(sc, I2C_100kHz); /* XXX rate */
309 1.3 macallan
310 1.3 macallan ki2c_writereg(sc, IER,I2C_INT_DATA|I2C_INT_ADDR|I2C_INT_STOP);
311 1.31.2.1 thorpej
312 1.31.2.1 thorpej /*
313 1.31.2.1 thorpej * Two physical I2C busses share a single controller. It's not
314 1.31.2.1 thorpej * quite a mux, which is why we don't attach it that way.
315 1.31.2.1 thorpej *
316 1.31.2.1 thorpej * The locking order is:
317 1.25 macallan *
318 1.31.2.1 thorpej * iic bus mutex -> ctrl_lock
319 1.31.2.1 thorpej *
320 1.31.2.1 thorpej * ctrl_lock is taken in ki2c_i2c_acquire_bus.
321 1.4 macallan */
322 1.31.2.1 thorpej mutex_init(&sc->sc_ctrl_lock, MUTEX_DEFAULT, IPL_NONE);
323 1.31.2.1 thorpej
324 1.31.2.1 thorpej /* Set up the channel structures. */
325 1.31.2.1 thorpej for (i = 0; i < KI2C_MAX_I2C_CHANNELS; i++) {
326 1.31.2.1 thorpej ch = &sc->sc_channels[i];
327 1.31.2.1 thorpej
328 1.31.2.1 thorpej iic_tag_init(&ch->ch_i2c);
329 1.31.2.1 thorpej ch->ch_i2c.ic_cookie = ch;
330 1.31.2.1 thorpej ch->ch_i2c.ic_acquire_bus = ki2c_i2c_acquire_bus;
331 1.31.2.1 thorpej ch->ch_i2c.ic_release_bus = ki2c_i2c_release_bus;
332 1.31.2.1 thorpej ch->ch_i2c.ic_exec = ki2c_i2c_exec;
333 1.28 macallan
334 1.31.2.1 thorpej ch->ch_ki2c = sc;
335 1.31.2.1 thorpej ch->ch_channel = i;
336 1.31.2.1 thorpej }
337 1.31.2.1 thorpej
338 1.31.2.1 thorpej /*
339 1.31.2.1 thorpej * Different systems have different I2C device tree topologies.
340 1.31.2.1 thorpej *
341 1.31.2.1 thorpej * Some systems use a scheme like this:
342 1.31.2.1 thorpej *
343 1.31.2.1 thorpej * /u3@0,f8000000/i2c@f8001000/temp-monitor@98
344 1.31.2.1 thorpej * /u3@0,f8000000/i2c@f8001000/fan@15e
345 1.31.2.1 thorpej *
346 1.31.2.1 thorpej * Here, we see the channel encoded in bit #8 of the address.
347 1.31.2.1 thorpej *
348 1.31.2.1 thorpej * Other systems use a scheme like this:
349 1.31.2.1 thorpej *
350 1.31.2.1 thorpej * /ht@0,f2000000/pci@4000,0,0/mac-io@7/i2c@18000/i2c-bus@0
351 1.31.2.1 thorpej * /ht@0,f2000000/pci@4000,0,0/mac-io@7/i2c@18000/i2c-bus@0/codec@8c
352 1.31.2.1 thorpej *
353 1.31.2.1 thorpej * /u4@0,f8000000/i2c@f8001000/i2c-bus@1
354 1.31.2.1 thorpej * /u4@0,f8000000/i2c@f8001000/i2c-bus@1/temp-monitor@94
355 1.31.2.1 thorpej *
356 1.31.2.1 thorpej * Here, a separate device tree node represents the channel.
357 1.31.2.1 thorpej * Note that in BOTH cases, the I2C address of the devices are
358 1.31.2.1 thorpej * shifted left by 1 (as it would be on the wire to leave room
359 1.31.2.1 thorpej * for the read/write bit).
360 1.31.2.1 thorpej *
361 1.31.2.1 thorpej * So, what we're going to do here is look for i2c-bus nodes. If
362 1.31.2.1 thorpej * we find them, we remember those phandles, and will use them for
363 1.31.2.1 thorpej * device enumeration. If we don't, then we will use the controller
364 1.31.2.1 thorpej * phandle for device enumeration and filter based on the channel
365 1.31.2.1 thorpej * bit in the "reg" property.
366 1.31.2.1 thorpej */
367 1.31.2.1 thorpej int i2c_bus_phandles[KI2C_MAX_I2C_CHANNELS] = { 0 };
368 1.31.2.1 thorpej bool separate_nodes_scheme = false;
369 1.31.2.1 thorpej for (child = OF_child(node); child != 0; child = OF_peer(child)) {
370 1.4 macallan OF_getprop(child, "name", name, sizeof(name));
371 1.25 macallan if (strcmp(name, "i2c-bus") == 0) {
372 1.31.2.1 thorpej separate_nodes_scheme = true;
373 1.31.2.1 thorpej if (of_getprop_uint32(child, "reg", &channel) == -1) {
374 1.31.2.1 thorpej continue;
375 1.31.2.1 thorpej }
376 1.31.2.1 thorpej if (channel >= KI2C_MAX_I2C_CHANNELS) {
377 1.31.2.1 thorpej continue;
378 1.28 macallan }
379 1.31.2.1 thorpej i2c_bus_phandles[channel] = child;
380 1.26 macallan }
381 1.3 macallan }
382 1.3 macallan
383 1.31.2.1 thorpej /*
384 1.31.2.1 thorpej * Set up our handle implementation (we provide our own
385 1.31.2.1 thorpej * i2c enumeration call).
386 1.31.2.1 thorpej */
387 1.31.2.1 thorpej devhandle = device_handle(self);
388 1.31.2.1 thorpej devhandle_impl_inherit(&sc->sc_devhandle_impl, devhandle.impl);
389 1.31.2.1 thorpej sc->sc_devhandle_impl.lookup_device_call =
390 1.31.2.1 thorpej ki2c_devhandle_lookup_device_call;
391 1.31.2.1 thorpej
392 1.31.2.1 thorpej for (i = 0; i < KI2C_MAX_I2C_CHANNELS; i++) {
393 1.31.2.1 thorpej int locs[I2CBUSCF_NLOCS];
394 1.31.2.1 thorpej
395 1.31.2.1 thorpej ch = &sc->sc_channels[i];
396 1.31.2.1 thorpej
397 1.31.2.1 thorpej if (separate_nodes_scheme) {
398 1.31.2.1 thorpej if (i2c_bus_phandles[i] == 0) {
399 1.31.2.1 thorpej /*
400 1.31.2.1 thorpej * This wasn't represented (either at all
401 1.31.2.1 thorpej * or not correctly) in the device tree,
402 1.31.2.1 thorpej * so skip attaching the "iic" instance.
403 1.31.2.1 thorpej */
404 1.31.2.1 thorpej continue;
405 1.31.2.1 thorpej }
406 1.31.2.1 thorpej devhandle = devhandle_from_of(i2c_bus_phandles[i]);
407 1.31.2.1 thorpej } else {
408 1.31.2.1 thorpej devhandle = device_handle(self);
409 1.31.2.1 thorpej }
410 1.31.2.1 thorpej devhandle.impl = &sc->sc_devhandle_impl;
411 1.1 grant
412 1.31.2.1 thorpej locs[I2CBUSCF_BUS] = ch->ch_channel;
413 1.1 grant
414 1.31.2.1 thorpej memset(&iba, 0, sizeof(iba));
415 1.31.2.1 thorpej iba.iba_tag = &ch->ch_i2c;
416 1.31.2.1 thorpej iba.iba_bus = ch->ch_channel;
417 1.31.2.1 thorpej config_found(sc->sc_dev, &iba, iicbus_print_multi,
418 1.31.2.1 thorpej CFARG_SUBMATCH, config_stdsubmatch,
419 1.31.2.1 thorpej CFARG_LOCATORS, locs,
420 1.31.2.1 thorpej CFARG_DEVHANDLE, devhandle,
421 1.31.2.1 thorpej CFARG_EOL);
422 1.31.2.1 thorpej }
423 1.1 grant
424 1.1 grant }
425 1.1 grant
426 1.31.2.1 thorpej static int
427 1.14 dsl ki2c_intr(struct ki2c_softc *sc)
428 1.1 grant {
429 1.1 grant u_int isr, x;
430 1.1 grant
431 1.1 grant isr = ki2c_readreg(sc, ISR);
432 1.1 grant if (isr & I2C_INT_ADDR) {
433 1.1 grant #if 0
434 1.1 grant if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) {
435 1.1 grant /* No slave responded. */
436 1.1 grant sc->sc_flags |= I2C_ERROR;
437 1.1 grant goto out;
438 1.1 grant }
439 1.1 grant #endif
440 1.1 grant
441 1.1 grant if (sc->sc_flags & I2C_READING) {
442 1.1 grant if (sc->sc_resid > 1) {
443 1.1 grant x = ki2c_readreg(sc, CONTROL);
444 1.1 grant x |= I2C_CT_AAK;
445 1.1 grant ki2c_writereg(sc, CONTROL, x);
446 1.1 grant }
447 1.1 grant } else {
448 1.1 grant ki2c_writereg(sc, DATA, *sc->sc_data++);
449 1.1 grant sc->sc_resid--;
450 1.1 grant }
451 1.1 grant }
452 1.1 grant
453 1.1 grant if (isr & I2C_INT_DATA) {
454 1.1 grant if (sc->sc_flags & I2C_READING) {
455 1.1 grant *sc->sc_data++ = ki2c_readreg(sc, DATA);
456 1.1 grant sc->sc_resid--;
457 1.1 grant
458 1.1 grant if (sc->sc_resid == 0) { /* Completed */
459 1.1 grant ki2c_writereg(sc, CONTROL, 0);
460 1.1 grant goto out;
461 1.1 grant }
462 1.1 grant } else {
463 1.1 grant #if 0
464 1.1 grant if ((ki2c_readreg(sc, STATUS) & I2C_ST_LASTAAK) == 0) {
465 1.1 grant /* No slave responded. */
466 1.1 grant sc->sc_flags |= I2C_ERROR;
467 1.1 grant goto out;
468 1.1 grant }
469 1.1 grant #endif
470 1.1 grant
471 1.1 grant if (sc->sc_resid == 0) {
472 1.1 grant x = ki2c_readreg(sc, CONTROL) | I2C_CT_STOP;
473 1.1 grant ki2c_writereg(sc, CONTROL, x);
474 1.1 grant } else {
475 1.1 grant ki2c_writereg(sc, DATA, *sc->sc_data++);
476 1.1 grant sc->sc_resid--;
477 1.1 grant }
478 1.1 grant }
479 1.1 grant }
480 1.1 grant
481 1.1 grant out:
482 1.1 grant if (isr & I2C_INT_STOP) {
483 1.1 grant ki2c_writereg(sc, CONTROL, 0);
484 1.1 grant sc->sc_flags &= ~I2C_BUSY;
485 1.1 grant }
486 1.1 grant
487 1.1 grant ki2c_writereg(sc, ISR, isr);
488 1.1 grant
489 1.1 grant return 1;
490 1.1 grant }
491 1.1 grant
492 1.31.2.1 thorpej static int
493 1.14 dsl ki2c_poll(struct ki2c_softc *sc, int timo)
494 1.1 grant {
495 1.1 grant while (sc->sc_flags & I2C_BUSY) {
496 1.1 grant if (ki2c_readreg(sc, ISR))
497 1.1 grant ki2c_intr(sc);
498 1.1 grant timo -= 100;
499 1.1 grant if (timo < 0) {
500 1.20 macallan DPRINTF("i2c_poll: timeout\n");
501 1.31.2.1 thorpej return ETIMEDOUT;
502 1.1 grant }
503 1.1 grant delay(100);
504 1.1 grant }
505 1.1 grant return 0;
506 1.1 grant }
507 1.1 grant
508 1.31.2.1 thorpej static int
509 1.15 dsl ki2c_start(struct ki2c_softc *sc, int addr, int subaddr, void *data, int len)
510 1.1 grant {
511 1.1 grant int rw = (sc->sc_flags & I2C_READING) ? 1 : 0;
512 1.31.2.1 thorpej int error, timo, x;
513 1.1 grant
514 1.1 grant KASSERT((addr & 1) == 0);
515 1.1 grant
516 1.1 grant sc->sc_data = data;
517 1.1 grant sc->sc_resid = len;
518 1.1 grant sc->sc_flags |= I2C_BUSY;
519 1.1 grant
520 1.1 grant timo = 1000 + len * 200;
521 1.1 grant
522 1.1 grant /* XXX TAS3001 sometimes takes 50ms to finish writing registers. */
523 1.1 grant /* if (addr == 0x68) */
524 1.1 grant timo += 100000;
525 1.1 grant
526 1.1 grant ki2c_writereg(sc, ADDR, addr | rw);
527 1.1 grant ki2c_writereg(sc, SUBADDR, subaddr);
528 1.1 grant
529 1.1 grant x = ki2c_readreg(sc, CONTROL) | I2C_CT_ADDR;
530 1.1 grant ki2c_writereg(sc, CONTROL, x);
531 1.1 grant
532 1.31.2.1 thorpej if ((error = ki2c_poll(sc, timo)) != 0)
533 1.31.2.1 thorpej return error;
534 1.31.2.1 thorpej
535 1.1 grant if (sc->sc_flags & I2C_ERROR) {
536 1.20 macallan DPRINTF("I2C_ERROR\n");
537 1.31.2.1 thorpej return EIO;
538 1.1 grant }
539 1.1 grant return 0;
540 1.1 grant }
541 1.1 grant
542 1.31.2.1 thorpej static int
543 1.15 dsl ki2c_read(struct ki2c_softc *sc, int addr, int subaddr, void *data, int len)
544 1.1 grant {
545 1.1 grant sc->sc_flags = I2C_READING;
546 1.20 macallan DPRINTF("ki2c_read: %02x %d\n", addr, len);
547 1.1 grant return ki2c_start(sc, addr, subaddr, data, len);
548 1.1 grant }
549 1.1 grant
550 1.31.2.1 thorpej static int
551 1.15 dsl ki2c_write(struct ki2c_softc *sc, int addr, int subaddr, void *data, int len)
552 1.1 grant {
553 1.1 grant sc->sc_flags = 0;
554 1.20 macallan DPRINTF("ki2c_write: %02x %d\n",addr,len);
555 1.3 macallan return ki2c_start(sc, addr, subaddr, data, len);
556 1.3 macallan }
557 1.3 macallan
558 1.31.2.1 thorpej static int
559 1.31.2.1 thorpej ki2c_i2c_acquire_bus(void * const v, int const flags)
560 1.31.2.1 thorpej {
561 1.31.2.1 thorpej struct ki2c_channel *ch = v;
562 1.31.2.1 thorpej struct ki2c_softc *sc = ch->ch_ki2c;
563 1.31.2.1 thorpej
564 1.31.2.1 thorpej if (flags & I2C_F_POLL) {
565 1.31.2.1 thorpej if (! mutex_tryenter(&sc->sc_ctrl_lock)) {
566 1.31.2.1 thorpej return EBUSY;
567 1.31.2.1 thorpej }
568 1.31.2.1 thorpej } else {
569 1.31.2.1 thorpej mutex_enter(&sc->sc_ctrl_lock);
570 1.31.2.1 thorpej }
571 1.31.2.1 thorpej return 0;
572 1.31.2.1 thorpej }
573 1.31.2.1 thorpej
574 1.31.2.1 thorpej static void
575 1.31.2.1 thorpej ki2c_i2c_release_bus(void * const v, int const flags)
576 1.31.2.1 thorpej {
577 1.31.2.1 thorpej struct ki2c_channel *ch = v;
578 1.31.2.1 thorpej struct ki2c_softc *sc = ch->ch_ki2c;
579 1.31.2.1 thorpej
580 1.31.2.1 thorpej mutex_exit(&sc->sc_ctrl_lock);
581 1.31.2.1 thorpej }
582 1.31.2.1 thorpej
583 1.3 macallan int
584 1.3 macallan ki2c_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *vcmd,
585 1.3 macallan size_t cmdlen, void *vbuf, size_t buflen, int flags)
586 1.3 macallan {
587 1.31.2.1 thorpej struct ki2c_channel *ch = cookie;
588 1.31.2.1 thorpej struct ki2c_softc *sc = ch->ch_ki2c;
589 1.31.2.1 thorpej int i, error;
590 1.12 pgoyette size_t w_len;
591 1.12 pgoyette uint8_t *wp;
592 1.12 pgoyette uint8_t wrbuf[I2C_EXEC_MAX_CMDLEN + I2C_EXEC_MAX_CMDLEN];
593 1.25 macallan uint8_t channel;
594 1.12 pgoyette
595 1.12 pgoyette /*
596 1.12 pgoyette * We don't have any idea if the ki2c controller can execute
597 1.12 pgoyette * i2c quick_{read,write} operations, so if someone tries one,
598 1.12 pgoyette * return an error.
599 1.12 pgoyette */
600 1.12 pgoyette if (cmdlen == 0 && buflen == 0)
601 1.31.2.1 thorpej return ENOTSUP;
602 1.12 pgoyette
603 1.31.2.1 thorpej /* Don't support 10-bit addressing. */
604 1.31.2.1 thorpej if (addr > 0x7f)
605 1.31.2.1 thorpej return ENOTSUP;
606 1.31.2.1 thorpej
607 1.31.2.1 thorpej channel = ch->ch_channel == 1 ? 0x10 : 0x00;
608 1.25 macallan
609 1.3 macallan /* we handle the subaddress stuff ourselves */
610 1.25 macallan ki2c_setmode(sc, channel | I2C_STDMODE);
611 1.28 macallan ki2c_setspeed(sc, I2C_50kHz);
612 1.3 macallan
613 1.12 pgoyette /* Write-buffer defaults to vcmd */
614 1.12 pgoyette wp = (uint8_t *)(__UNCONST(vcmd));
615 1.12 pgoyette w_len = cmdlen;
616 1.12 pgoyette
617 1.12 pgoyette /*
618 1.12 pgoyette * Concatenate vcmd and vbuf for write operations
619 1.12 pgoyette *
620 1.12 pgoyette * Drivers written specifically for ki2c might already do this,
621 1.12 pgoyette * but "generic" i2c drivers still provide separate arguments
622 1.12 pgoyette * for the cmd and buf parts of iic_smbus_write_{byte,word}.
623 1.12 pgoyette */
624 1.12 pgoyette if (I2C_OP_WRITE_P(op) && buflen != 0) {
625 1.12 pgoyette if (cmdlen == 0) {
626 1.12 pgoyette wp = (uint8_t *)vbuf;
627 1.12 pgoyette w_len = buflen;
628 1.12 pgoyette } else {
629 1.12 pgoyette KASSERT((cmdlen + buflen) <= sizeof(wrbuf));
630 1.12 pgoyette wp = (uint8_t *)(__UNCONST(vcmd));
631 1.12 pgoyette w_len = 0;
632 1.12 pgoyette for (i = 0; i < cmdlen; i++)
633 1.12 pgoyette wrbuf[w_len++] = *wp++;
634 1.12 pgoyette wp = (uint8_t *)vbuf;
635 1.12 pgoyette for (i = 0; i < buflen; i++)
636 1.12 pgoyette wrbuf[w_len++] = *wp++;
637 1.12 pgoyette wp = wrbuf;
638 1.12 pgoyette }
639 1.12 pgoyette }
640 1.12 pgoyette
641 1.31.2.1 thorpej if (w_len > 0) {
642 1.31.2.1 thorpej error = ki2c_write(sc, addr << 1, 0, wp, w_len);
643 1.31.2.1 thorpej if (error) {
644 1.31.2.1 thorpej return error;
645 1.31.2.1 thorpej }
646 1.31.2.1 thorpej }
647 1.10 garbled
648 1.10 garbled if (I2C_OP_READ_P(op)) {
649 1.31.2.1 thorpej error = ki2c_read(sc, addr << 1, 0, vbuf, buflen);
650 1.31.2.1 thorpej if (error) {
651 1.31.2.1 thorpej return error;
652 1.31.2.1 thorpej }
653 1.3 macallan }
654 1.3 macallan return 0;
655 1.1 grant }
656