2 * Copyright (c) 1998, 2001 Nicolas Souchu
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/sys/dev/iicbus/iic.c,v 1.43 2009/01/26 13:53:39 raj Exp $
29 #include <sys/param.h>
33 #include <sys/fcntl.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/systm.h>
40 #include <bus/iicbus/iiconf.h>
41 #include <bus/iicbus/iicbus.h>
42 #include <bus/iicbus/iic.h>
44 #include "iicbus_if.h"
51 u_char sc_addr
; /* 7 bit address on iicbus */
52 int sc_count
; /* >0 if device opened */
54 char sc_buffer
[BUFSIZE
]; /* output buffer */
55 char sc_inbuf
[BUFSIZE
]; /* input buffer */
61 #define IIC_UNLOCK(sc)
63 static int iic_probe(device_t
);
64 static int iic_attach(device_t
);
65 static int iic_detach(device_t
);
66 static void iic_identify(driver_t
*driver
, device_t parent
);
68 static devclass_t iic_devclass
;
70 static device_method_t iic_methods
[] = {
71 /* device interface */
72 DEVMETHOD(device_identify
, iic_identify
),
73 DEVMETHOD(device_probe
, iic_probe
),
74 DEVMETHOD(device_attach
, iic_attach
),
75 DEVMETHOD(device_detach
, iic_detach
),
77 /* iicbus interface */
78 DEVMETHOD(iicbus_intr
, iicbus_generic_intr
),
83 static driver_t iic_driver
= {
86 sizeof(struct iic_softc
),
89 static d_open_t iicopen
;
90 static d_close_t iicclose
;
91 static d_write_t iicwrite
;
92 static d_read_t iicread
;
93 static d_ioctl_t iicioctl
;
95 static struct dev_ops iic_ops
= {
105 iic_identify(driver_t
*driver
, device_t parent
)
108 if (device_find_child(parent
, "iic", -1) == NULL
)
109 BUS_ADD_CHILD(parent
, parent
, 0, "iic", -1);
113 iic_probe(device_t dev
)
115 if (iicbus_get_addr(dev
) > 0)
118 device_set_desc(dev
, "I2C generic I/O");
124 iic_attach(device_t dev
)
126 struct iic_softc
*sc
= (struct iic_softc
*)device_get_softc(dev
);
128 sc
->sc_devnode
= make_dev(&iic_ops
, device_get_unit(dev
),
130 0600, "iic%d", device_get_unit(dev
));
131 if (sc
->sc_devnode
== NULL
) {
132 device_printf(dev
, "failed to create character device\n");
135 sc
->sc_devnode
->si_drv1
= sc
;
141 iic_detach(device_t dev
)
143 struct iic_softc
*sc
= (struct iic_softc
*)device_get_softc(dev
);
146 dev_ops_remove_minor(&iic_ops
, device_get_unit(dev
));
152 iicopen(struct dev_open_args
*ap
)
154 cdev_t dev
= ap
->a_head
.a_dev
;
155 struct iic_softc
*sc
= dev
->si_drv1
;
158 if (sc
->sc_count
> 0) {
170 iicclose(struct dev_close_args
*ap
)
172 cdev_t dev
= ap
->a_head
.a_dev
;
173 struct iic_softc
*sc
= dev
->si_drv1
;
177 /* XXX: I don't think this can happen. */
184 if (sc
->sc_count
< 0)
185 panic("%s: iic_count < 0!", __func__
);
192 iicwrite(struct dev_write_args
*ap
)
194 cdev_t dev
= ap
->a_head
.a_dev
;
195 struct uio
*uio
= ap
->a_uio
;
196 struct iic_softc
*sc
= dev
->si_drv1
;
197 device_t iicdev
= sc
->sc_dev
;
198 int sent
, error
, count
;
206 if (sc
->sc_count
== 0) {
207 /* XXX: I don't think this can happen. */
212 error
= iicbus_request_bus(device_get_parent(iicdev
), iicdev
,
219 count
= (int)szmin(uio
->uio_resid
, BUFSIZE
);
220 uiomove(sc
->sc_buffer
, (size_t)count
, uio
);
222 error
= iicbus_block_write(device_get_parent(iicdev
), sc
->sc_addr
,
223 sc
->sc_buffer
, count
, &sent
);
225 iicbus_release_bus(device_get_parent(iicdev
), iicdev
);
232 iicread(struct dev_read_args
*ap
)
234 cdev_t dev
= ap
->a_head
.a_dev
;
235 struct uio
*uio
= ap
->a_uio
;
236 struct iic_softc
*sc
= dev
->si_drv1
;
237 device_t iicdev
= sc
->sc_dev
;
247 if (sc
->sc_count
== 0) {
248 /* XXX: I don't think this can happen. */
253 error
= iicbus_request_bus(device_get_parent(iicdev
), iicdev
,
260 /* max amount of data to read */
261 len
= (int)szmin(uio
->uio_resid
, BUFSIZE
);
263 error
= iicbus_block_read(device_get_parent(iicdev
), sc
->sc_addr
,
264 sc
->sc_inbuf
, len
, &bufsize
);
270 if (bufsize
> uio
->uio_resid
)
271 panic("%s: too much data read!", __func__
);
273 iicbus_release_bus(device_get_parent(iicdev
), iicdev
);
275 error
= uiomove(sc
->sc_inbuf
, (size_t)bufsize
, uio
);
281 iicioctl(struct dev_ioctl_args
*ap
)
283 cdev_t dev
= ap
->a_head
.a_dev
;
284 u_long cmd
= ap
->a_cmd
;
285 caddr_t data
= ap
->a_data
;
286 int flags
= ap
->a_fflag
;
287 struct iic_softc
*sc
= dev
->si_drv1
;
288 device_t iicdev
= sc
->sc_dev
;
289 device_t parent
= device_get_parent(iicdev
);
290 struct iiccmd
*s
= (struct iiccmd
*)data
;
291 struct iic_rdwr_data
*d
= (struct iic_rdwr_data
*)data
;
295 void **usrbufs
= NULL
;
297 if ((error
= iicbus_request_bus(device_get_parent(iicdev
), iicdev
,
298 (flags
& O_NONBLOCK
) ? IIC_DONTWAIT
:
299 (IIC_WAIT
| IIC_INTR
))))
305 error
= iicbus_start(parent
, s
->slave
, 0);
308 * Implicitly set the chip addr to the slave addr passed as
309 * parameter. Consequently, start/stop shall be called before
310 * the read or the write of a block.
313 sc
->sc_addr
= s
->slave
;
319 error
= iicbus_stop(parent
);
323 error
= iicbus_reset(parent
, IIC_UNKNOWN
, 0, NULL
);
331 buf
= kmalloc((unsigned long)s
->count
, M_TEMP
, M_WAITOK
);
332 error
= copyin(s
->buf
, buf
, s
->count
);
335 error
= iicbus_write(parent
, buf
, s
->count
, &count
, 10);
343 buf
= kmalloc((unsigned long)s
->count
, M_TEMP
, M_WAITOK
);
344 error
= iicbus_read(parent
, buf
, s
->count
, &count
, s
->last
, 10);
347 error
= copyout(buf
, s
->buf
, s
->count
);
351 buf
= kmalloc(sizeof(*d
->msgs
) * d
->nmsgs
, M_TEMP
, M_WAITOK
);
352 usrbufs
= kmalloc(sizeof(void *) * d
->nmsgs
, M_TEMP
, M_ZERO
| M_WAITOK
);
353 error
= copyin(d
->msgs
, buf
, sizeof(*d
->msgs
) * d
->nmsgs
);
356 /* Alloc kernel buffers for userland data, copyin write data */
357 for (i
= 0; i
< d
->nmsgs
; i
++) {
358 m
= &((struct iic_msg
*)buf
)[i
];
360 m
->buf
= kmalloc(m
->len
, M_TEMP
, M_WAITOK
);
361 if (!(m
->flags
& IIC_M_RD
))
362 copyin(usrbufs
[i
], m
->buf
, m
->len
);
364 error
= iicbus_transfer(parent
, (struct iic_msg
*)buf
, d
->nmsgs
);
365 /* Copyout all read segments, free up kernel buffers */
366 for (i
= 0; i
< d
->nmsgs
; i
++) {
367 m
= &((struct iic_msg
*)buf
)[i
];
368 if (m
->flags
& IIC_M_RD
)
369 copyout(m
->buf
, usrbufs
[i
], m
->len
);
370 kfree(m
->buf
, M_TEMP
);
372 kfree(usrbufs
, M_TEMP
);
376 error
= iicbus_repeated_start(parent
, s
->slave
, 0);
383 iicbus_release_bus(device_get_parent(iicdev
), iicdev
);
390 DRIVER_MODULE(iic
, iicbus
, iic_driver
, iic_devclass
, NULL
, NULL
);
391 MODULE_DEPEND(iic
, iicbus
, IICBUS_MINVER
, IICBUS_PREFVER
, IICBUS_MAXVER
);
392 MODULE_VERSION(iic
, 1);