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