Home | History | Annotate | Line # | Download | only in i2c
i2c.c revision 1.46
      1 /*	$NetBSD: i2c.c,v 1.45 2014/12/07 00:32:35 jmcneill Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2003 Wasabi Systems, Inc.
      5  * All rights reserved.
      6  *
      7  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. All advertising materials mentioning features or use of this software
     18  *    must display the following acknowledgement:
     19  *      This product includes software developed for the NetBSD Project by
     20  *      Wasabi Systems, Inc.
     21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     22  *    or promote products derived from this software without specific prior
     23  *    written permission.
     24  *
     25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35  * POSSIBILITY OF SUCH DAMAGE.
     36  */
     37 
     38 #ifdef _KERNEL_OPT
     39 #include "opt_i2c.h"
     40 #endif
     41 
     42 #include <sys/cdefs.h>
     43 __KERNEL_RCSID(0, "$NetBSD: i2c.c,v 1.45 2014/12/07 00:32:35 jmcneill Exp $");
     44 
     45 #include <sys/param.h>
     46 #include <sys/systm.h>
     47 #include <sys/device.h>
     48 #include <sys/event.h>
     49 #include <sys/conf.h>
     50 #include <sys/malloc.h>
     51 #include <sys/kmem.h>
     52 #include <sys/kthread.h>
     53 #include <sys/proc.h>
     54 #include <sys/kernel.h>
     55 #include <sys/fcntl.h>
     56 #include <sys/module.h>
     57 
     58 #include <dev/i2c/i2cvar.h>
     59 
     60 #include "locators.h"
     61 
     62 #ifndef I2C_MAX_ADDR
     63 #define I2C_MAX_ADDR	0x3ff	/* 10-bit address, max */
     64 #endif
     65 
     66 struct iic_softc {
     67 	i2c_tag_t sc_tag;
     68 	int sc_type;
     69 	device_t sc_devices[I2C_MAX_ADDR + 1];
     70 };
     71 
     72 static dev_type_open(iic_open);
     73 static dev_type_close(iic_close);
     74 static dev_type_ioctl(iic_ioctl);
     75 
     76 const struct cdevsw iic_cdevsw = {
     77 	.d_open = iic_open,
     78 	.d_close = iic_close,
     79 	.d_read = noread,
     80 	.d_write = nowrite,
     81 	.d_ioctl = iic_ioctl,
     82 	.d_stop = nostop,
     83 	.d_tty = notty,
     84 	.d_poll = nopoll,
     85 	.d_mmap = nommap,
     86 	.d_kqfilter = nokqfilter,
     87 	.d_discard = nodiscard,
     88 	.d_flag = D_OTHER
     89 };
     90 
     91 extern struct cfdriver iic_cd;
     92 
     93 static void	iic_smbus_intr_thread(void *);
     94 static void	iic_fill_compat(struct i2c_attach_args*, const char*,
     95 			size_t, char **);
     96 
     97 static int
     98 iic_print_direct(void *aux, const char *pnp)
     99 {
    100 	struct i2c_attach_args *ia = aux;
    101 
    102 	if (pnp != NULL)
    103 		aprint_normal("%s at %s addr 0x%02x", ia->ia_name, pnp,
    104 			ia->ia_addr);
    105 	else
    106 		aprint_normal(" addr 0x%02x", ia->ia_addr);
    107 
    108 	return UNCONF;
    109 }
    110 
    111 static int
    112 iic_print(void *aux, const char *pnp)
    113 {
    114 	struct i2c_attach_args *ia = aux;
    115 
    116 	if (ia->ia_addr != (i2c_addr_t)-1)
    117 		aprint_normal(" addr 0x%x", ia->ia_addr);
    118 
    119 	return UNCONF;
    120 }
    121 
    122 static int
    123 iic_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
    124 {
    125 	struct iic_softc *sc = device_private(parent);
    126 	struct i2c_attach_args ia;
    127 
    128 	ia.ia_tag = sc->sc_tag;
    129 	ia.ia_size = cf->cf_loc[IICCF_SIZE];
    130 	ia.ia_type = sc->sc_type;
    131 
    132 	ia.ia_name = NULL;
    133 	ia.ia_ncompat = 0;
    134 	ia.ia_compat = NULL;
    135 
    136 	for (ia.ia_addr = 0; ia.ia_addr <= I2C_MAX_ADDR; ia.ia_addr++) {
    137 		if (sc->sc_devices[ia.ia_addr] != NULL)
    138 			continue;
    139 
    140 		if (cf->cf_loc[IICCF_ADDR] != -1 &&
    141 		    cf->cf_loc[IICCF_ADDR] != ia.ia_addr)
    142 			continue;
    143 
    144 		if (config_match(parent, cf, &ia) > 0)
    145 			sc->sc_devices[ia.ia_addr] =
    146 			    config_attach(parent, cf, &ia, iic_print);
    147 	}
    148 
    149 	return 0;
    150 }
    151 
    152 static void
    153 iic_child_detach(device_t parent, device_t child)
    154 {
    155 	struct iic_softc *sc = device_private(parent);
    156 	int i;
    157 
    158 	for (i = 0; i <= I2C_MAX_ADDR; i++)
    159 		if (sc->sc_devices[i] == child) {
    160 			sc->sc_devices[i] = NULL;
    161 			break;
    162 		}
    163 }
    164 
    165 static int
    166 iic_rescan(device_t self, const char *ifattr, const int *locators)
    167 {
    168 	config_search_ia(iic_search, self, ifattr, NULL);
    169 	return 0;
    170 }
    171 
    172 static int
    173 iic_match(device_t parent, cfdata_t cf, void *aux)
    174 {
    175 
    176 	return 1;
    177 }
    178 
    179 static void
    180 iic_attach(device_t parent, device_t self, void *aux)
    181 {
    182 	struct iic_softc *sc = device_private(self);
    183 	struct i2cbus_attach_args *iba = aux;
    184 	prop_array_t child_devices;
    185 	prop_dictionary_t props;
    186 	char *buf;
    187 	i2c_tag_t ic;
    188 	int rv;
    189 	bool indirect_config;
    190 
    191 	aprint_naive("\n");
    192 	aprint_normal(": I2C bus\n");
    193 
    194 	sc->sc_tag = iba->iba_tag;
    195 	sc->sc_type = iba->iba_type;
    196 	ic = sc->sc_tag;
    197 	ic->ic_devname = device_xname(self);
    198 
    199 	LIST_INIT(&(sc->sc_tag->ic_list));
    200 	LIST_INIT(&(sc->sc_tag->ic_proc_list));
    201 
    202 	rv = kthread_create(PRI_NONE, KTHREAD_MUSTJOIN, NULL,
    203 	    iic_smbus_intr_thread, ic, &ic->ic_intr_thread,
    204 	    "%s", ic->ic_devname);
    205 	if (rv)
    206 		aprint_error_dev(self, "unable to create intr thread\n");
    207 
    208 	if (!pmf_device_register(self, NULL, NULL))
    209 		aprint_error_dev(self, "couldn't establish power handler\n");
    210 
    211 	props = device_properties(parent);
    212 	if (!prop_dictionary_get_bool(props, "i2c-indirect-config",
    213 	    &indirect_config))
    214 		indirect_config = true;
    215 	child_devices = prop_dictionary_get(props, "i2c-child-devices");
    216 	if (child_devices) {
    217 		unsigned int i, count;
    218 		prop_dictionary_t dev;
    219 		prop_data_t cdata;
    220 		uint32_t addr, size;
    221 		uint64_t cookie;
    222 		const char *name;
    223 		struct i2c_attach_args ia;
    224 		int loc[2];
    225 
    226 		memset(loc, 0, sizeof loc);
    227 		count = prop_array_count(child_devices);
    228 		for (i = 0; i < count; i++) {
    229 			dev = prop_array_get(child_devices, i);
    230 			if (!dev) continue;
    231  			if (!prop_dictionary_get_cstring_nocopy(
    232 			    dev, "name", &name))
    233 				continue;
    234 			if (!prop_dictionary_get_uint32(dev, "addr", &addr))
    235 				continue;
    236 			if (!prop_dictionary_get_uint64(dev, "cookie", &cookie))
    237 				cookie = 0;
    238 			loc[0] = addr;
    239 			if (prop_dictionary_get_uint32(dev, "size", &size))
    240 				loc[1] = size;
    241 			else
    242 				loc[1] = -1;
    243 
    244 			memset(&ia, 0, sizeof ia);
    245 			ia.ia_addr = addr;
    246 			ia.ia_type = sc->sc_type;
    247 			ia.ia_tag = ic;
    248 			ia.ia_name = name;
    249 			ia.ia_cookie = cookie;
    250 			ia.ia_size = size;
    251 
    252 			buf = NULL;
    253 			cdata = prop_dictionary_get(dev, "compatible");
    254 			if (cdata)
    255 				iic_fill_compat(&ia,
    256 				    prop_data_data_nocopy(cdata),
    257 				    prop_data_size(cdata), &buf);
    258 
    259 			if (addr > I2C_MAX_ADDR) {
    260 				aprint_error_dev(self,
    261 				    "WARNING: ignoring bad device address "
    262 				    "@ 0x%02x\n", addr);
    263 			} else if (sc->sc_devices[addr] == NULL) {
    264 				sc->sc_devices[addr] =
    265 				    config_found_sm_loc(self, "iic", loc, &ia,
    266 					iic_print_direct, NULL);
    267 			}
    268 
    269 			if (ia.ia_compat)
    270 				free(ia.ia_compat, M_TEMP);
    271 			if (buf)
    272 				free(buf, M_TEMP);
    273 		}
    274 	} else if (indirect_config) {
    275 		/*
    276 		 * Attach all i2c devices described in the kernel
    277 		 * configuration file.
    278 		 */
    279 		iic_rescan(self, "iic", NULL);
    280 	}
    281 }
    282 
    283 static int
    284 iic_detach(device_t self, int flags)
    285 {
    286 	struct iic_softc *sc = device_private(self);
    287 	i2c_tag_t ic = sc->sc_tag;
    288 	int i, error;
    289 	void *hdl;
    290 
    291 	for (i = 0; i <= I2C_MAX_ADDR; i++) {
    292 		if (sc->sc_devices[i]) {
    293 			error = config_detach(sc->sc_devices[i], flags);
    294 			if (error)
    295 				return error;
    296 		}
    297 	}
    298 
    299 	if (ic->ic_running) {
    300 		ic->ic_running = 0;
    301 		wakeup(ic);
    302 		kthread_join(ic->ic_intr_thread);
    303 	}
    304 
    305 	if (!LIST_EMPTY(&ic->ic_list)) {
    306 		device_printf(self, "WARNING: intr handler list not empty\n");
    307 		while (!LIST_EMPTY(&ic->ic_list)) {
    308 			hdl = LIST_FIRST(&ic->ic_list);
    309 			iic_smbus_intr_disestablish(ic, hdl);
    310 		}
    311 	}
    312 	if (!LIST_EMPTY(&ic->ic_proc_list)) {
    313 		device_printf(self, "WARNING: proc handler list not empty\n");
    314 		while (!LIST_EMPTY(&ic->ic_proc_list)) {
    315 			hdl = LIST_FIRST(&ic->ic_proc_list);
    316 			iic_smbus_intr_disestablish_proc(ic, hdl);
    317 		}
    318 	}
    319 
    320 	pmf_device_deregister(self);
    321 
    322 	return 0;
    323 }
    324 
    325 static void
    326 iic_smbus_intr_thread(void *aux)
    327 {
    328 	i2c_tag_t ic;
    329 	struct ic_intr_list *il;
    330 
    331 	ic = (i2c_tag_t)aux;
    332 	ic->ic_running = 1;
    333 	ic->ic_pending = 0;
    334 
    335 	while (ic->ic_running) {
    336 		if (ic->ic_pending == 0)
    337 			tsleep(ic, PZERO, "iicintr", hz);
    338 		if (ic->ic_pending > 0) {
    339 			LIST_FOREACH(il, &(ic->ic_proc_list), il_next) {
    340 				(*il->il_intr)(il->il_intrarg);
    341 			}
    342 			ic->ic_pending--;
    343 		}
    344 	}
    345 
    346 	kthread_exit(0);
    347 }
    348 
    349 void *
    350 iic_smbus_intr_establish(i2c_tag_t ic, int (*intr)(void *), void *intrarg)
    351 {
    352 	struct ic_intr_list *il;
    353 
    354 	il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK);
    355 	if (il == NULL)
    356 		return NULL;
    357 
    358 	il->il_intr = intr;
    359 	il->il_intrarg = intrarg;
    360 
    361 	LIST_INSERT_HEAD(&(ic->ic_list), il, il_next);
    362 
    363 	return il;
    364 }
    365 
    366 void
    367 iic_smbus_intr_disestablish(i2c_tag_t ic, void *hdl)
    368 {
    369 	struct ic_intr_list *il;
    370 
    371 	il = (struct ic_intr_list *)hdl;
    372 
    373 	LIST_REMOVE(il, il_next);
    374 	free(il, M_DEVBUF);
    375 
    376 	return;
    377 }
    378 
    379 void *
    380 iic_smbus_intr_establish_proc(i2c_tag_t ic, int (*intr)(void *), void *intrarg)
    381 {
    382 	struct ic_intr_list *il;
    383 
    384 	il = malloc(sizeof(struct ic_intr_list), M_DEVBUF, M_WAITOK);
    385 	if (il == NULL)
    386 		return NULL;
    387 
    388 	il->il_intr = intr;
    389 	il->il_intrarg = intrarg;
    390 
    391 	LIST_INSERT_HEAD(&(ic->ic_proc_list), il, il_next);
    392 
    393 	return il;
    394 }
    395 
    396 void
    397 iic_smbus_intr_disestablish_proc(i2c_tag_t ic, void *hdl)
    398 {
    399 	struct ic_intr_list *il;
    400 
    401 	il = (struct ic_intr_list *)hdl;
    402 
    403 	LIST_REMOVE(il, il_next);
    404 	free(il, M_DEVBUF);
    405 
    406 	return;
    407 }
    408 
    409 int
    410 iic_smbus_intr(i2c_tag_t ic)
    411 {
    412 	struct ic_intr_list *il;
    413 
    414 	LIST_FOREACH(il, &(ic->ic_list), il_next) {
    415 		(*il->il_intr)(il->il_intrarg);
    416 	}
    417 
    418 	ic->ic_pending++;
    419 	wakeup(ic);
    420 
    421 	return 1;
    422 }
    423 
    424 static void
    425 iic_fill_compat(struct i2c_attach_args *ia, const char *compat, size_t len,
    426 	char **buffer)
    427 {
    428 	int count, i;
    429 	const char *c, *start, **ptr;
    430 
    431 	*buffer = NULL;
    432 	for (i = count = 0, c = compat; i < len; i++, c++)
    433 		if (*c == 0)
    434 			count++;
    435 	count += 2;
    436 	ptr = malloc(sizeof(char*)*count, M_TEMP, M_WAITOK);
    437 	if (!ptr) return;
    438 
    439 	for (i = count = 0, start = c = compat; i < len; i++, c++) {
    440 		if (*c == 0) {
    441 			ptr[count++] = start;
    442 			start = c+1;
    443 		}
    444 	}
    445 	if (start < compat+len) {
    446 		/* last string not 0 terminated */
    447 		size_t l = c-start;
    448 		*buffer = malloc(l+1, M_TEMP, M_WAITOK);
    449 		memcpy(*buffer, start, l);
    450 		(*buffer)[l] = 0;
    451 		ptr[count++] = *buffer;
    452 	}
    453 	ptr[count] = NULL;
    454 
    455 	ia->ia_compat = ptr;
    456 	ia->ia_ncompat = count;
    457 }
    458 
    459 int
    460 iic_compat_match(struct i2c_attach_args *ia, const char ** compats)
    461 {
    462 	int i;
    463 
    464 	for (; compats && *compats; compats++) {
    465 		for (i = 0; i < ia->ia_ncompat; i++) {
    466 			if (strcmp(*compats, ia->ia_compat[i]) == 0)
    467 				return 1;
    468 		}
    469 	}
    470 	return 0;
    471 }
    472 
    473 static int
    474 iic_open(dev_t dev, int flag, int fmt, lwp_t *l)
    475 {
    476 	struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev));
    477 
    478 	if (sc == NULL)
    479 		return ENXIO;
    480 
    481 	return 0;
    482 }
    483 
    484 static int
    485 iic_close(dev_t dev, int flag, int fmt, lwp_t *l)
    486 {
    487 	return 0;
    488 }
    489 
    490 static int
    491 iic_ioctl_exec(struct iic_softc *sc, i2c_ioctl_exec_t *iie, int flag)
    492 {
    493 	i2c_tag_t ic = sc->sc_tag;
    494 	uint8_t buf[I2C_EXEC_MAX_BUFLEN];
    495 	void *cmd = NULL;
    496 	int error;
    497 
    498 	/* Validate parameters */
    499 	if (iie->iie_addr > I2C_MAX_ADDR)
    500 		return EINVAL;
    501 	if (iie->iie_cmdlen > I2C_EXEC_MAX_CMDLEN ||
    502 	    iie->iie_buflen > I2C_EXEC_MAX_BUFLEN)
    503 		return EINVAL;
    504 	if (iie->iie_cmd != NULL && iie->iie_cmdlen == 0)
    505 		return EINVAL;
    506 	if (iie->iie_buf != NULL && iie->iie_buflen == 0)
    507 		return EINVAL;
    508 	if (I2C_OP_WRITE_P(iie->iie_op) && (flag & FWRITE) == 0)
    509 		return EBADF;
    510 
    511 #if 0
    512 	/* Disallow userspace access to devices that have drivers attached. */
    513 	if (sc->sc_devices[iie->iie_addr] != NULL)
    514 		return EBUSY;
    515 #endif
    516 
    517 	if (iie->iie_cmd != NULL) {
    518 		cmd = kmem_alloc(iie->iie_cmdlen, KM_SLEEP);
    519 		if (cmd == NULL)
    520 			return ENOMEM;
    521 		error = copyin(iie->iie_cmd, cmd, iie->iie_cmdlen);
    522 		if (error) {
    523 			kmem_free(cmd, iie->iie_cmdlen);
    524 			return error;
    525 		}
    526 	}
    527 
    528 	if (iie->iie_buf != NULL && I2C_OP_WRITE_P(iie->iie_op)) {
    529 		error = copyin(iie->iie_buf, buf, iie->iie_buflen);
    530 		if (error) {
    531 			return error;
    532 		}
    533 	}
    534 
    535 	iic_acquire_bus(ic, 0);
    536 	error = iic_exec(ic, iie->iie_op, iie->iie_addr, cmd, iie->iie_cmdlen,
    537 	    buf, iie->iie_buflen, 0);
    538 	iic_release_bus(ic, 0);
    539 
    540 	/*
    541 	 * Some drivers return error codes on failure, and others return -1.
    542 	 */
    543 	if (error < 0)
    544 		error = EIO;
    545 
    546 	if (cmd)
    547 		kmem_free(cmd, iie->iie_cmdlen);
    548 
    549 	if (error)
    550 		return error;
    551 
    552 	if (iie->iie_buf != NULL && I2C_OP_READ_P(iie->iie_op))
    553 		error = copyout(buf, iie->iie_buf, iie->iie_buflen);
    554 
    555 	return error;
    556 }
    557 
    558 static int
    559 iic_ioctl(dev_t dev, u_long cmd, void *data, int flag, lwp_t *l)
    560 {
    561 	struct iic_softc *sc = device_lookup_private(&iic_cd, minor(dev));
    562 
    563 	if (sc == NULL)
    564 		return ENXIO;
    565 
    566 	switch (cmd) {
    567 	case I2C_IOCTL_EXEC:
    568 		return iic_ioctl_exec(sc, (i2c_ioctl_exec_t *)data, flag);
    569 	default:
    570 		return ENODEV;
    571 	}
    572 }
    573 
    574 
    575 CFATTACH_DECL2_NEW(iic, sizeof(struct iic_softc),
    576     iic_match, iic_attach, iic_detach, NULL, iic_rescan, iic_child_detach);
    577 
    578 MODULE(MODULE_CLASS_DRIVER, iic, NULL);
    579 
    580 #ifdef _MODULE
    581 #include "ioconf.c"
    582 #endif
    583 
    584 static int
    585 iic_modcmd(modcmd_t cmd, void *opaque)
    586 {
    587 	int error;
    588 
    589 	error = 0;
    590 	switch (cmd) {
    591 	case MODULE_CMD_INIT:
    592 #ifdef _MODULE
    593 		error = config_init_component(cfdriver_ioconf_iic,
    594 		    cfattach_ioconf_iic, cfdata_ioconf_iic);
    595 		if (error)
    596 			aprint_error("%s: unable to init component\n",
    597 			    iic_cd.cd_name);
    598 #endif
    599 		break;
    600 	case MODULE_CMD_FINI:
    601 #ifdef _MODULE
    602 		config_fini_component(cfdriver_ioconf_iic,
    603 		    cfattach_ioconf_iic, cfdata_ioconf_iic);
    604 #endif
    605 		break;
    606 	default:
    607 		error = ENOTTY;
    608 	}
    609 	return error;
    610 }
    611