48#include "opt_platform.h"
51#include <sys/kernel.h>
53#include <sys/module.h>
55#include <sys/sysctl.h>
59#include <dev/ofw/ofw_bus.h>
60#include <dev/ofw/ofw_bus_subr.h>
61#include <dev/fdt/fdt_common.h>
67#include <dev/smbus/smbconf.h>
73#define DEFAULT_SCL_LOW_TIMEOUT (25 * 1000)
92static int iicbb_write(device_t,
const char *,
int,
int *,
int);
93static int iicbb_read(device_t,
char *,
int,
int *,
int,
int);
94static int iicbb_reset(device_t, u_char, u_char, u_char *);
98static phandle_t iicbb_get_node(device_t, device_t);
123 DEVMETHOD(ofw_bus_get_node, iicbb_get_node),
140 device_set_desc(
dev,
"I2C bit-banging driver");
150 sc->
iicbus = device_add_child(
dev,
"iicbus", -1);
156 SYSCTL_ADD_UINT(device_get_sysctl_ctx(
dev),
157 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
158 "delay", CTLFLAG_RD, &sc->
udelay,
159 0,
"Signal change delay controlled by bus frequency, microseconds");
161 SYSCTL_ADD_UINT(device_get_sysctl_ctx(
dev),
162 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
164 0,
"SCL low timeout, microseconds");
165 SYSCTL_ADD_UINT(device_get_sysctl_ctx(
dev),
166 SYSCTL_CHILDREN(device_get_sysctl_tree(
dev)), OID_AUTO,
168 0,
"Estimate of pin toggling latency, microseconds");
170 bus_generic_attach(
dev);
178 bus_generic_detach(
dev);
179 device_delete_children(
dev);
186iicbb_get_node(device_t bus, device_t
dev)
190 return (ofw_bus_get_node(bus));
210 retval += bus_print_child_header(bus,
dev);
214 retval += printf(
" on %s master-only\n",
215 device_get_nameunit(bus));
220 retval += printf(
" on %s addr 0x%x\n",
221 device_get_nameunit(bus),
oldaddr & 0xff);
233 &
i2c_debug, 0,
"Enable i2c bit-banging driver debug");
235#define I2C_DEBUG(x) do { \
236 if (i2c_debug) (x); \
242#define I2C_GETSDA(dev) (IICBB_GETSDA(device_get_parent(dev)))
243#define I2C_SETSDA(dev, x) (IICBB_SETSDA(device_get_parent(dev), x))
244#define I2C_GETSCL(dev) (IICBB_GETSCL(device_get_parent(dev)))
245#define I2C_SETSCL(dev, x) (IICBB_SETSCL(device_get_parent(dev), x))
251 sbintime_t fast_timeout;
256 fast_timeout = now + SBT_1MS;
262 }
while (now < fast_timeout);
265 pause_sbt(
"iicbb-scl-low", SBT_1MS, C_PREL(8), 0);
357 for (t = 0; t < sc->
udelay; t++) {
367 I2C_DEBUG(printf(
"%c ", noack ?
'-' :
'+'));
376 for (i = 7; i >= 0; i--) {
400 for (i = 7; i >= 0; i--) {
407 DELAY((sc->
udelay + 1) / 2);
410 DELAY((sc->
udelay + 1) / 2);
426 return (IICBB_CALLBACK(device_get_parent(
dev),
index,
data));
457 DELAY((sc->
udelay + 1) / 2);
473 DELAY((sc->
udelay + 1) / 2);
515 DELAY((sc->
udelay + 1) / 2);
517 DELAY((sc->
udelay + 1) / 2);
519 I2C_DEBUG(printf(
"%s>>", err != 0 ?
"!" :
""));
528 int bytes, error = 0;
573 error = IICBB_PRE_XFER(device_get_parent(
dev));
579 IICBB_POST_XFER(device_get_parent(
dev));
593 period = 1000000 / 2 / busfreq;
595 sc->
udelay = MAX(period, 1);
static int iicbb_getack(device_t dev)
static int iicbb_sendbyte(device_t dev, uint8_t data)
static int iicbb_stop(device_t)
#define DEFAULT_SCL_LOW_TIMEOUT
#define I2C_SETSCL(dev, x)
#define I2C_SETSDA(dev, x)
static device_method_t iicbb_methods[]
static void iicbb_set_speed(struct iicbb_softc *sc, u_char)
static int iicbb_start(device_t, u_char, int)
static int iicbb_read(device_t, char *, int, int *, int, int)
static int iicbb_print_child(device_t, device_t)
static int iicbb_write(device_t, const char *, int, int *, int)
static int iicbb_callback(device_t, int, caddr_t)
static int iicbb_repstart(device_t, u_char, int)
static int iicbb_readbyte(device_t dev, bool last, uint8_t *data)
static void iicbb_clockout(device_t dev)
static int iicbb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
static int iicbb_probe(device_t)
static int iicbb_start_impl(device_t dev, u_char slave, bool repstart)
MODULE_DEPEND(iicbb, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER)
MODULE_VERSION(iicbb, IICBB_MODVER)
devclass_t iicbb_devclass
static int iicbb_sendbit(device_t dev, int bit)
DRIVER_MODULE(iicbus, iicbb, iicbus_driver, iicbus_devclass, 0, 0)
static int iicbb_attach(device_t)
static int iicbb_clockin(device_t dev, int sda)
SYSCTL_INT(_hw_i2c, OID_AUTO, iicbb_debug, CTLFLAG_RWTUN, &i2c_debug, 0, "Enable i2c bit-banging driver debug")
static int iicbb_reset(device_t, u_char, u_char, u_char *)
static int iicbb_detach(device_t)
static int iicbb_waitforscl(device_t dev)
static void iicbb_child_detached(device_t, device_t)
devclass_t iicbus_devclass
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_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)
int iicbus_transfer_gen(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
#define iicbus_reset(bus, speed, addr, oldaddr)