36#include <sys/kernel.h>
37#include <sys/malloc.h>
38#include <sys/module.h>
63#define IIC_LOCK(cdp) sx_xlock(&(cdp)->lock)
64#define IIC_UNLOCK(cdp) sx_xunlock(&(cdp)->lock)
71static void iic_identify(driver_t *driver, device_t parent);
74static int iicuio(
struct cdev *
dev,
struct uio *uio,
int ioflag);
102 .d_version = D_VERSION,
114 if (device_find_child(parent,
"iic", -1) == NULL)
115 BUS_ADD_CHILD(parent, 0,
"iic", -1);
121 if (iicbus_get_addr(
dev) > 0)
124 device_set_desc(
dev,
"I2C generic I/O");
134 sc = device_get_softc(
dev);
138 0600,
"iic%d", device_get_unit(
dev));
140 device_printf(
dev,
"failed to create character device\n");
153 sc = device_get_softc(
dev);
162iicopen(
struct cdev *
dev,
int flags,
int fmt,
struct thread *td)
167 priv = malloc(
sizeof(*priv), M_IIC, M_WAITOK | M_ZERO);
169 sx_init(&priv->
lock,
"iic");
170 priv->
sc =
dev->si_drv1;
172 error = devfs_set_cdevpriv(priv,
iicdtor);
182 device_t iicdev, parent;
186 KASSERT(priv != NULL, (
"iic cdevpriv should not be NULL!"));
189 parent = device_get_parent(iicdev);
197 sx_destroy(&priv->
lock);
205 int error, num_bytes, transferred_bytes, written_bytes;
208 parent = device_get_parent(priv->
sc->
sc_dev);
215 while ((error == 0) && (uio->uio_resid > 0)) {
217 num_bytes = MIN(uio->uio_resid,
sizeof(buffer));
218 transferred_bytes = 0;
220 if (uio->uio_rw == UIO_WRITE) {
221 error = uiomove(buffer, num_bytes, uio);
223 while ((error == 0) && (transferred_bytes < num_bytes)) {
225 error =
iicbus_write(parent, &buffer[transferred_bytes],
226 num_bytes - transferred_bytes, &written_bytes, 0);
227 transferred_bytes += written_bytes;
230 }
else if (uio->uio_rw == UIO_READ) {
232 num_bytes, &transferred_bytes,
233 ((uio->uio_resid <=
sizeof(buffer)) ?
last : 0), 0);
235 error = uiomove(buffer, transferred_bytes, uio);
251 error = devfs_get_cdevpriv((
void**)&priv);
255 KASSERT(priv != NULL, (
"iic cdevpriv should not be NULL!"));
262 parent = device_get_parent(priv->
sc->
sc_dev);
271 if (uio->uio_rw == UIO_READ)
297 device_t iicdev, parent;
302 parent = device_get_parent(iicdev);
308 buf = malloc(
sizeof(*d->
msgs) * d->
nmsgs, M_IIC, M_WAITOK);
317 usrbufs = malloc(
sizeof(
void *) * d->
nmsgs, M_IIC, M_WAITOK | M_ZERO);
319 for (i = 0; i < d->
nmsgs; i++) {
332 m->
buf = malloc(m->
len, M_IIC, M_WAITOK);
334 error = copyin(usrbufs[i], m->
buf, m->
len);
347 for (i = 0; i < d->
nmsgs; i++) {
350 error = copyout(m->
buf, usrbufs[i], m->
len);
354 free(usrbufs, M_IIC);
362 device_t parent, iicdev;
370 error = devfs_get_cdevpriv((
void**)&priv);
374 KASSERT(priv != NULL, (
"iic cdevpriv should not be NULL!"));
377 parent = device_get_parent(iicdev);
439 uvec.iov_base = s->
buf;
440 uvec.iov_len = s->
count;
441 ubuf.uio_iov = &uvec;
443 ubuf.uio_segflg = UIO_USERSPACE;
445 ubuf.uio_resid = s->
count;
447 ubuf.uio_rw = UIO_WRITE;
456 uvec.iov_base = s->
buf;
457 uvec.iov_len = s->
count;
458 ubuf.uio_iov = &uvec;
460 ubuf.uio_segflg = UIO_USERSPACE;
462 ubuf.uio_resid = s->
count;
464 ubuf.uio_rw = UIO_READ;
MODULE_DEPEND(iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER)
static int iicuio(struct cdev *dev, struct uio *uio, int ioflag)
static int iic_attach(device_t)
static devclass_t iic_devclass
static struct cdevsw iic_cdevsw
static driver_t iic_driver
static int iic_probe(device_t)
static void iic_identify(driver_t *driver, device_t parent)
DRIVER_MODULE(iic, iicbus, iic_driver, iic_devclass, 0, 0)
static int iicrdwr(struct iic_cdevpriv *priv, struct iic_rdwr_data *d, int flags)
static int iic_detach(device_t)
static device_method_t iic_methods[]
static void iicdtor(void *data)
static d_ioctl_t iicioctl
static MALLOC_DEFINE(M_IIC, "iic", "I2C device data")
static int iicuio_move(struct iic_cdevpriv *priv, struct uio *uio, int last)
#define IIC_RDRW_MAX_MSGS
int iicbus_generic_intr(device_t dev, int event, char *buf)
int iicbus_request_bus(device_t bus, device_t dev, int how)
void iicbus_intr(device_t bus, int event, char *buf)
int iicbus_transfer(device_t bus, struct iic_msg *msgs, uint32_t nmsgs)
int iicbus_read(device_t bus, char *buf, int len, int *read, int last, int delay)
int iicbus_release_bus(device_t bus, device_t dev)
int iicbus_write(device_t bus, const char *buf, int len, int *sent, int timeout)
int iicbus_stop(device_t bus)
int iicbus_repeated_start(device_t bus, u_char slave, int timeout)
int iicbus_start(device_t bus, u_char slave, int timeout)
#define iicbus_reset(bus, speed, addr, oldaddr)