33#include "opt_platform.h"
39#include <sys/kernel.h>
40#include <sys/module.h>
41#include <sys/resource.h>
43#include <sys/sysctl.h>
45#include <machine/bus.h>
48#include <dev/ofw/ofw_bus.h>
49#include <dev/ofw/ofw_bus_subr.h>
83static struct eeprom_desc type_desc[] = {
84 { 8, 128, 8,
"AT24C01"},
85 { 8, 256, 8,
"AT24C02"},
86 { 8, 512, 16,
"AT24C04"},
87 { 8, 1024, 16,
"AT24C08"},
88 { 8, 2 * 1024, 16,
"AT24C16"},
89 {16, 4 * 1024, 32,
"AT24C32"},
90 {16, 8 * 1024, 32,
"AT24C64"},
91 {16, 16 * 1024, 64,
"AT24C128"},
92 {16, 32 * 1024, 64,
"AT24C256"},
93 {16, 64 * 1024, 128,
"AT24C512"},
94 {16, 128 * 1024, 256,
"AT24CM01"},
98 {
"atmel,24c01", (uintptr_t)(&type_desc[0])},
99 {
"atmel,24c02", (uintptr_t)(&type_desc[1])},
100 {
"atmel,24c04", (uintptr_t)(&type_desc[2])},
101 {
"atmel,24c08", (uintptr_t)(&type_desc[3])},
102 {
"atmel,24c16", (uintptr_t)(&type_desc[4])},
103 {
"atmel,24c32", (uintptr_t)(&type_desc[5])},
104 {
"atmel,24c64", (uintptr_t)(&type_desc[6])},
105 {
"atmel,24c128", (uintptr_t)(&type_desc[7])},
106 {
"atmel,24c256", (uintptr_t)(&type_desc[8])},
107 {
"atmel,24c512", (uintptr_t)(&type_desc[9])},
108 {
"atmel,24c1024", (uintptr_t)(&type_desc[10])},
109 {NULL, (uintptr_t)NULL},
113#define CDEV2SOFTC(dev) ((dev)->si_drv1)
121 .d_version = D_VERSION,
130 struct eeprom_desc *d;
132 if (!ofw_bus_status_okay(
dev))
135 d = (
struct eeprom_desc *)
138 device_set_desc(
dev, d->name);
139 return (BUS_PROBE_DEFAULT);
142 device_set_desc(
dev,
"I2C EEPROM");
143 return (BUS_PROBE_NOWILDCARD);
152 struct eeprom_desc *d;
154 d = (
struct eeprom_desc *)
159 sc->
wr_sz = d->wr_sz;
163 dname = device_get_name(sc->
dev);
164 dunit = device_get_unit(sc->
dev);
165 if (resource_int_value(dname, dunit,
"type", &sc->
type) != 0)
167 if (resource_int_value(dname, dunit,
"size", &sc->
size) != 0)
169 if (resource_int_value(dname, dunit,
"wr_sz", &sc->
wr_sz) != 0)
178 struct sysctl_ctx_list *ctx;
179 struct sysctl_oid_list *tree;
182 sc->
addr = iicbus_get_addr(
dev);
186 device_printf(
dev,
"size: %d bytes, addressing: %d-bits\n",
189 GID_WHEEL, 0600,
"icee%d", device_get_unit(
dev));
190 if (sc->
cdev == NULL) {
193 sc->
cdev->si_drv1 = sc;
195 ctx = device_get_sysctl_ctx(
dev);
196 tree = SYSCTL_CHILDREN(device_get_sysctl_tree(
dev));
197 SYSCTL_ADD_INT(ctx, tree, OID_AUTO,
"address_size", CTLFLAG_RD,
198 &sc->
type, 0,
"Memory array address size in bits");
199 SYSCTL_ADD_INT(ctx, tree, OID_AUTO,
"device_size", CTLFLAG_RD,
200 &sc->
size, 0,
"Memory array capacity in bytes");
201 SYSCTL_ADD_INT(ctx, tree, OID_AUTO,
"write_size", CTLFLAG_RD,
202 &sc->
wr_sz, 0,
"Memory array page write size in bytes");
212 destroy_dev(sc->
cdev);
229 if (uio->uio_offset == sc->
size)
231 if (uio->uio_offset > sc->
size)
233 if (sc->
type != 8 && sc->
type != 16)
236 while (uio->uio_resid > 0) {
237 if (uio->uio_offset >= sc->
size)
243 slave = (uio->uio_offset >> 7) | sc->
addr;
246 addr[0] = uio->uio_offset & 0xff;
249 slave = sc->
addr | (uio->uio_offset >> 15);
252 addr[0] = (uio->uio_offset >> 8) & 0xff;
253 addr[1] = uio->uio_offset & 0xff;
256 for (i = 0; i < 2; i++)
263 error = uiomove(
data,
len, uio);
290 if (uio->uio_offset >= sc->
size)
292 if (sc->
type != 8 && sc->
type != 16)
296 while (uio->uio_resid > 0) {
297 if (uio->uio_offset >= sc->
size)
303 slave = (uio->uio_offset >> 7) | sc->
addr;
305 data[0] = uio->uio_offset & 0xff;
308 slave = sc->
addr | (uio->uio_offset >> 15);
310 data[0] = (uio->uio_offset >> 8) & 0xff;
311 data[1] = uio->uio_offset & 0xff;
329 }
while (waitlimit-- > 0 && error != 0);
static ds13_compat_data compat_data[]
static int icee_init(struct icee_softc *sc)
DRIVER_MODULE(icee, iicbus, icee_driver, icee_devclass, 0, 0)
static struct cdevsw icee_cdevsw
static d_write_t icee_write
static int icee_detach(device_t dev)
static int icee_probe(device_t dev)
IICBUS_FDT_PNP_INFO(compat_data)
static d_read_t icee_read
static driver_t icee_driver
MODULE_DEPEND(icee, iicbus, 1, 1, 1)
static devclass_t icee_devclass
static device_method_t icee_methods[]
static int icee_attach(device_t dev)
struct iic_reqbus_data * rd
int iic2errno(int iic_status)
int iicbus_transfer_excl(device_t dev, struct iic_msg *msgs, uint32_t nmsgs, int how)