Page MenuHomeFreeBSD

D8172.id21134.diff
No OneTemporary

D8172.id21134.diff

Index: share/man/man4/cyapa.4
===================================================================
--- share/man/man4/cyapa.4
+++ share/man/man4/cyapa.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2015
+.Dd October 03, 2016
.Dt CYAPA 4
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Bd -ragged -offset indent
.Cd "device cyapa"
.Cd "device ig4"
-.Cd "device smbus"
+.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the following line in
@@ -45,6 +45,13 @@
cyapa_load="YES"
ig4_load="YES"
.Ed
+.Pp
+In
+.Pa /boot/device.hints :
+.Cd hint.cyapa.0.at="iicbus0"
+.Cd hint.cyapa.0.addr="0xCE"
+.Cd hint.cyapa.1.at="iicbus1"
+.Cd hint.cyapa.1.addr="0xCE"
.Sh DESCRIPTION
The
.Nm
@@ -86,6 +93,23 @@
The lower right corner issues a RIGHT button.
Optionally, tap to click can be enabled (see below).
.El
+.Pp
+On a
+.Xr device.hints 5
+based system
+these values are configurable for
+.Nm :
+.Bl -tag -width ".Va hint.cyapa.%d.addr"
+.It Va hint.cyapa.%d.at
+is the
+.Xr iicbus 4
+you are attaching to.
+.It Va hint.cyapa.%d.addr
+is the
+.Nm
+i2c address on the
+.Xr iicbus 4 .
+.El
.Sh SYSCTL VARIABLES
These
.Xr sysctl 8
@@ -175,7 +199,7 @@
.Dl debug.cyapa_enable_tapclick=2
.Sh SEE ALSO
.Xr ig4 4 ,
-.Xr smbus 4 ,
+.Xr iicbus 4 ,
.Xr sysmouse 4 ,
.Xr moused 8
.Sh AUTHORS
@@ -195,6 +219,6 @@
.Sh BUGS
The
.Nm
-driver detects the device based on its I2C address (0x67).
+driver detects the device based on its I2C address.
This might have unforeseen consequences if the initialization sequence
is sent to an unknown device at that address.
Index: share/man/man4/ig4.4
===================================================================
--- share/man/man4/ig4.4
+++ share/man/man4/ig4.4
@@ -24,18 +24,18 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 30, 2015
+.Dd October 03, 2016
.Dt IG4 4
.Os
.Sh NAME
.Nm ig4
-.Nd Intel(R) fourth generation mobile CPU integrated I2C SMBus driver
+.Nd Intel(R) fourth generation mobile CPU integrated I2C driver
.Sh SYNOPSIS
To compile this driver into the kernel, place the following lines into
the kernel configuration file:
.Bd -ragged -offset indent
.Cd "device ig4"
-.Cd "device smbus"
+.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the following line in
@@ -46,9 +46,10 @@
.Sh DESCRIPTION
The
.Nm
-driver provides access to peripherals attached to an I2C SMB controller.
+driver provides access to peripherals attached to an I2C controller.
+.Sh HARDWARE
.Nm
-supports the SMBus controller found in fourth generation Intel(R) Core(TM)
+supports the I2C controllers found in fourth generation Intel(R) Core(TM)
processors based on the mobile U-processor line for intelligent systems.
This includes the i7-4650U, i5-4300U, i3-4010U, and 2980U.
.Sh SYSCTL VARIABLES
@@ -57,13 +58,15 @@
variables are available:
.Bl -tag -width "debug.ig4_dump"
.It Va debug.ig4_dump
-Setting this to a non-zero value dumps controller registers to console and
-syslog once.
-The sysctl resets to zero immediately.
+This sysctl is a bit mask.
+If a bit is set to 1, then a register dump is printed
+every time there is an operation an
+.Nm
+device with the same unit number as the zero-based bit number.
.El
.Sh SEE ALSO
-.Xr smb 4 ,
-.Xr smbus 4
+.Xr iic 4 ,
+.Xr iicbus 4
.Sh AUTHORS
.An -nosplit
The
Index: share/man/man4/isl.4
===================================================================
--- share/man/man4/isl.4
+++ share/man/man4/isl.4
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2015
+.Dd October 03, 2016
.Dt ISL 4
.Os
.Sh NAME
@@ -36,7 +36,7 @@
.Bd -ragged -offset indent
.Cd "device isl"
.Cd "device ig4"
-.Cd "device smbus"
+.Cd "device iicbus"
.Ed
.Pp
Alternatively, to load the driver as a module at boot time, place the following line in
@@ -45,6 +45,13 @@
isl_load="YES"
ig4_load="YES"
.Ed
+.Pp
+In
+.Pa /boot/device.hints :
+.Cd hint.isl.0.at="iicbus0"
+.Cd hint.isl.0.addr="0x88"
+.Cd hint.isl.1.at="iicbus1"
+.Cd hint.isl.1.addr="0x88"
.Sh DESCRIPTION
The
.Nm
@@ -54,6 +61,23 @@
Functionality is basic and provided through the
.Xr sysctl 8
interface.
+.Pp
+On a
+.Xr device.hints 5
+based system
+these values are configurable for
+.Nm :
+.Bl -tag -width ".Va hint.isl.%d.addr"
+.It Va hint.isl.%d.at
+is the
+.Xr iicbus 4
+you are attaching to.
+.It Va hint.isl.%d.addr
+is the
+.Nm
+i2c address on the
+.Xr iicbus 4 .
+.El
.Sh SYSCTL VARIABLES
The following
.Xr sysctl 8
@@ -86,7 +110,7 @@
.Ed
.Sh SEE ALSO
.Xr ig4 4 ,
-.Xr smbus 4
+.Xr iicbus 4
.Sh AUTHORS
.An -nosplit
The
@@ -99,6 +123,6 @@
.Sh BUGS
The
.Nm
-driver detects the device based on its I2C address (0x44).
+driver detects the device based on its I2C address.
This might have unforeseen consequences if the initialization sequence
is sent to an unknown device at that address.
Index: sys/dev/cyapa/cyapa.c
===================================================================
--- sys/dev/cyapa/cyapa.c
+++ sys/dev/cyapa/cyapa.c
@@ -122,11 +122,11 @@
#include <sys/uio.h>
#include <sys/vnode.h>
-#include <dev/smbus/smbconf.h>
-#include <dev/smbus/smbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
#include <dev/cyapa/cyapa.h>
-#include "smbus_if.h"
+#include "iicbus_if.h"
#include "bus_if.h"
#include "device_if.h"
@@ -149,7 +149,6 @@
struct cyapa_softc {
device_t dev;
int count; /* >0 if device opened */
- int addr;
struct cdev *devnode;
struct selinfo selinfo;
struct mtx mutex;
@@ -273,6 +272,30 @@
SYSCTL_INT(_debug, OID_AUTO, cyapa_reset, CTLFLAG_RW,
&cyapa_reset, 0, "Reset track pad");
+static int
+cyapa_read_bytes(device_t dev, uint8_t reg, uint8_t *val, int cnt)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
+ { addr, IIC_M_RD, cnt, val },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
+
+static int
+cyapa_write_bytes(device_t dev, uint8_t reg, const uint8_t *val, int cnt)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
+ { addr, IIC_M_WR | IIC_M_NOSTART, cnt, __DECONST(uint8_t *, val) },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
+
static void
cyapa_lock(struct cyapa_softc *sc)
{
@@ -318,7 +341,7 @@
* Initialize the device
*/
static int
-init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe)
+init_device(device_t dev, struct cyapa_cap *cap, int probe)
{
static char bl_exit[] = {
0x00, 0xff, 0xa5, 0x00, 0x01,
@@ -326,17 +349,13 @@
static char bl_deactivate[] = {
0x00, 0xff, 0x3b, 0x00, 0x01,
0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
- device_t bus;
struct cyapa_boot_regs boot;
int error;
int retries;
- bus = device_get_parent(dev); /* smbus */
-
/* Get status */
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&boot, sizeof(boot), NULL);
+ error = cyapa_read_bytes(dev, CMD_BOOT_STATUS,
+ (void *)&boot, sizeof(boot));
if (error)
goto done;
@@ -350,25 +369,21 @@
/* Busy, wait loop. */
} else if (boot.error & CYAPA_ERROR_BOOTLOADER) {
/* Magic */
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_deactivate, sizeof(bl_deactivate),
- NULL, 0, NULL);
+ error = cyapa_write_bytes(dev, CMD_BOOT_STATUS,
+ bl_deactivate, sizeof(bl_deactivate));
if (error)
goto done;
} else {
/* Magic */
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_exit, sizeof(bl_exit), NULL, 0, NULL);
+ error = cyapa_write_bytes(dev, CMD_BOOT_STATUS,
+ bl_exit, sizeof(bl_exit));
if (error)
goto done;
}
pause("cyapab1", (hz * 2) / 10);
--retries;
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&boot, sizeof(boot), NULL);
+ error = cyapa_read_bytes(dev, CMD_BOOT_STATUS,
+ (void *)&boot, sizeof(boot));
if (error)
goto done;
}
@@ -381,9 +396,8 @@
/* Check identity */
if (cap) {
- error = smbus_trans(bus, addr, CMD_QUERY_CAPABILITIES,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)cap, sizeof(*cap), NULL);
+ error = cyapa_read_bytes(dev, CMD_QUERY_CAPABILITIES,
+ (void *)cap, sizeof(*cap));
if (strncmp(cap->prod_ida, "CYTRA", 5) != 0) {
device_printf(dev, "Product ID \"%5.5s\" mismatch\n",
@@ -391,9 +405,8 @@
error = ENXIO;
}
}
- error = smbus_trans(bus, addr, CMD_BOOT_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&boot, sizeof(boot), NULL);
+ error = cyapa_read_bytes(dev, CMD_BOOT_STATUS,
+ (void *)&boot, sizeof(boot));
if (probe == 0) /* official init */
device_printf(dev, "cyapa init status %02x\n", boot.stat);
@@ -452,16 +465,16 @@
int addr;
int error;
- addr = smbus_get_addr(dev);
+ addr = iicbus_get_addr(dev);
/*
* 0x67 - cypress trackpad on the acer c720
* (other devices might use other ids).
*/
- if (addr != 0x67)
+ if (addr != 0xce)
return (ENXIO);
- error = init_device(dev, &cap, addr, 1);
+ error = init_device(dev, &cap, 1);
if (error != 0)
return (ENXIO);
@@ -482,15 +495,14 @@
sc->reporting_mode = 1;
unit = device_get_unit(dev);
- addr = smbus_get_addr(dev);
+ addr = iicbus_get_addr(dev);
- if (init_device(dev, &cap, addr, 0))
+ if (init_device(dev, &cap, 0))
return (ENXIO);
mtx_init(&sc->mutex, "cyapa", NULL, MTX_DEF);
sc->dev = dev;
- sc->addr = addr;
knlist_init_mtx(&sc->selinfo.si_note, &sc->mutex);
@@ -1159,7 +1171,7 @@
{
struct cyapa_softc *sc;
struct cyapa_regs regs;
- device_t bus; /* smbus */
+ device_t bus; /* iicbus */
int error;
int freq;
int isidle;
@@ -1180,12 +1192,10 @@
while (!sc->detaching) {
cyapa_unlock(sc);
- error = smbus_request_bus(bus, sc->dev, SMB_WAIT);
+ error = iicbus_request_bus(bus, sc->dev, IIC_WAIT);
if (error == 0) {
- error = smbus_trans(bus, sc->addr, CMD_DEV_STATUS,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0,
- (void *)&regs, sizeof(regs), NULL);
+ error = cyapa_read_bytes(sc->dev, CMD_DEV_STATUS,
+ (void *)&regs, sizeof(regs));
if (error == 0) {
isidle = cyapa_raw_input(sc, &regs, freq);
}
@@ -1200,9 +1210,9 @@
(unsigned)(ticks - last_reset) > TIME_TO_RESET)) {
cyapa_reset = 0;
last_reset = ticks;
- init_device(sc->dev, NULL, sc->addr, 2);
+ init_device(sc->dev, NULL, 2);
}
- smbus_release_bus(bus, sc->dev);
+ iicbus_release_bus(bus, sc->dev);
}
pause("cyapw", hz / freq);
++sc->poll_ticks;
@@ -1531,18 +1541,16 @@
int error;
bus = device_get_parent(sc->dev);
- error = smbus_request_bus(bus, sc->dev, SMB_WAIT);
+ error = iicbus_request_bus(bus, sc->dev, IIC_WAIT);
if (error == 0) {
- error = smbus_trans(bus, sc->addr, CMD_POWER_MODE,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, (void *)&data, 1, NULL);
+ error = cyapa_read_bytes(sc->dev, CMD_POWER_MODE,
+ &data, 1);
data = (data & ~0xFC) | mode;
if (error == 0) {
- error = smbus_trans(bus, sc->addr, CMD_POWER_MODE,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- (void *)&data, 1, NULL, 0, NULL);
+ error = cyapa_write_bytes(sc->dev, CMD_POWER_MODE,
+ &data, 1);
}
- smbus_release_bus(bus, sc->dev);
+ iicbus_release_bus(bus, sc->dev);
}
}
@@ -1697,6 +1705,6 @@
return (delta);
}
-DRIVER_MODULE(cyapa, smbus, cyapa_driver, cyapa_devclass, NULL, NULL);
-MODULE_DEPEND(cyapa, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+DRIVER_MODULE(cyapa, iicbus, cyapa_driver, cyapa_devclass, NULL, NULL);
+MODULE_DEPEND(cyapa, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
MODULE_VERSION(cyapa, 1);
Index: sys/dev/ichiic/ig4_iic.c
===================================================================
--- sys/dev/ichiic/ig4_iic.c
+++ sys/dev/ichiic/ig4_iic.c
@@ -61,6 +61,8 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/smbus/smbconf.h>
+#include <dev/iicbus/iicbus.h>
+#include <dev/iicbus/iiconf.h>
#include <dev/ichiic/ig4_reg.h>
#include <dev/ichiic/ig4_var.h>
@@ -120,7 +122,7 @@
reg_write(sc, IG4_REG_INTR_MASK, 0);
reg_write(sc, IG4_REG_I2C_EN, ctl);
- error = SMB_ETIMEOUT;
+ error = IIC_ETIMEOUT;
for (retry = 100; retry > 0; --retry) {
v = reg_read(sc, IG4_REG_ENABLE_STATUS);
@@ -148,7 +150,7 @@
u_int count_us = 0;
u_int limit_us = 25000; /* 25ms */
- error = SMB_ETIMEOUT;
+ error = IIC_ETIMEOUT;
for (;;) {
/*
@@ -484,6 +486,236 @@
}
/*
+ * IICBUS API FUNCTIONS
+ */
+static int
+ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave)
+{
+ /* XXX 10-bit address support? */
+ set_slave_addr(sc, slave >> 1, 0);
+ return (0);
+}
+
+static int
+ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
+ bool repeated_start, bool stop)
+{
+ uint32_t cmd;
+ uint16_t i;
+ int error;
+
+ if (len == 0)
+ return (0);
+
+ cmd = IG4_DATA_COMMAND_RD;
+ cmd |= repeated_start ? IG4_DATA_RESTART : 0;
+ cmd |= stop && len == 1 ? IG4_DATA_STOP : 0;
+
+ /* Issue request for the first byte (could be last as well). */
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+
+ for (i = 0; i < len; i++) {
+ /*
+ * Maintain a pipeline by queueing the allowance for the next
+ * read before waiting for the current read.
+ */
+ cmd = IG4_DATA_COMMAND_RD;
+ if (i < len - 1) {
+ cmd = IG4_DATA_COMMAND_RD;
+ cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0;
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+ }
+ error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY);
+ if (error)
+ break;
+ buf[i] = data_read(sc);
+ }
+
+ (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
+ return (error);
+}
+
+static int
+ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len,
+ bool repeated_start, bool stop)
+{
+ uint32_t cmd;
+ uint16_t i;
+ int error;
+
+ if (len == 0)
+ return (0);
+
+ cmd = repeated_start ? IG4_DATA_RESTART : 0;
+ for (i = 0; i < len; i++) {
+ error = wait_status(sc, IG4_STATUS_TX_NOTFULL);
+ if (error)
+ break;
+ cmd |= buf[i];
+ cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0;
+ reg_write(sc, IG4_REG_DATA_CMD, cmd);
+ cmd = 0;
+ }
+
+ (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE);
+ return (error);
+}
+
+int
+ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+ const char *reason = NULL;
+ uint32_t i;
+ int error;
+ int unit;
+ bool rpstart;
+ bool stop;
+
+ /*
+ * The hardware interface imposes limits on allowed I2C messages.
+ * It is not possible to explcitly send a start or stop.
+ * They are automatically sent (or not sent, depending on the
+ * configuration) when a data byte is tranferred.
+ * For this reason it's impossible to send a message with no data
+ * at all (like an SMBus quick message).
+ * The start condition is automatically generated after the stop
+ * condition, so it's impossible to not have a start after a stop.
+ * The repeated start condition is automatically send if a change
+ * of the transfer direction happens, so it's impossible to have
+ * a change of direction without a (repeated) start.
+ * The repeated start can be forced even without the change of
+ * direction.
+ * Changing the target slave address requires resetting the hardware
+ * state, so it's impossible to do that without the stop followed
+ * by the start.
+ */
+ for (i = 0; i < nmsgs; i++) {
+#if 0
+ if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) {
+ reason = "first message without start";
+ break;
+ }
+ if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) {
+ reason = "last message without stop";
+ break;
+ }
+#endif
+ if (msgs[i].len == 0) {
+ reason = "message with no data";
+ break;
+ }
+ if (i > 0) {
+ if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
+ (msgs[i - 1].flags & IIC_M_NOSTOP) == 0) {
+ reason = "stop not followed by start";
+ break;
+ }
+ if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 &&
+ msgs[i].slave != msgs[i - 1].slave) {
+ reason = "change of slave without stop";
+ break;
+ }
+ if ((msgs[i].flags & IIC_M_NOSTART) != 0 &&
+ (msgs[i].flags & IIC_M_RD) !=
+ (msgs[i - 1].flags & IIC_M_RD)) {
+ reason = "change of direction without repeated"
+ " start";
+ break;
+ }
+ }
+ }
+ if (reason != NULL) {
+ if (bootverbose)
+ device_printf(dev, "%s\n", reason);
+ return (IIC_ENOTSUPP);
+ }
+
+ sx_xlock(&sc->call_lock);
+ mtx_lock(&sc->io_lock);
+
+ /* Debugging - dump registers. */
+ if (ig4_dump) {
+ unit = device_get_unit(dev);
+ if (ig4_dump & (1 << unit)) {
+ ig4_dump &= ~(1 << unit);
+ ig4iic_dump(sc);
+ }
+ }
+
+ /*
+ * Clear any previous abort condition that may have been holding
+ * the txfifo in reset.
+ */
+ reg_read(sc, IG4_REG_CLR_TX_ABORT);
+
+ /*
+ * Clean out any previously received data.
+ */
+ if (sc->rpos != sc->rnext && bootverbose) {
+ device_printf(sc->dev, "discarding %d bytes of spurious data\n",
+ sc->rnext - sc->rpos);
+ }
+ sc->rpos = 0;
+ sc->rnext = 0;
+
+ rpstart = false;
+ error = 0;
+ for (i = 0; i < nmsgs; i++) {
+ if ((msgs[i].flags & IIC_M_NOSTART) == 0) {
+ error = ig4iic_xfer_start(sc, msgs[i].slave);
+ } else {
+ if (!sc->slave_valid ||
+ (msgs[i].slave >> 1) != sc->last_slave) {
+ device_printf(dev, "start condition suppressed"
+ "but slave address is not set up");
+ error = EINVAL;
+ break;
+ }
+ rpstart = false;
+ }
+ if (error != 0)
+ break;
+
+ stop = (msgs[i].flags & IIC_M_NOSTOP) == 0;
+ if (msgs[i].flags & IIC_M_RD)
+ error = ig4iic_read(sc, msgs[i].buf, msgs[i].len,
+ rpstart, stop);
+ else
+ error = ig4iic_write(sc, msgs[i].buf, msgs[i].len,
+ rpstart, stop);
+ if (error != 0)
+ break;
+
+ rpstart = !stop;
+ }
+
+ mtx_unlock(&sc->io_lock);
+ sx_unlock(&sc->call_lock);
+ return (error);
+}
+
+int
+ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr)
+{
+ ig4iic_softc_t *sc = device_get_softc(dev);
+
+ sx_xlock(&sc->call_lock);
+ mtx_lock(&sc->io_lock);
+
+ /* TODO handle speed configuration? */
+ if (oldaddr != NULL)
+ *oldaddr = sc->last_slave << 1;
+ set_slave_addr(sc, addr >> 1, 0);
+ if (addr == IIC_UNKNOWN)
+ sc->slave_valid = false;
+
+ mtx_unlock(&sc->io_lock);
+ sx_unlock(&sc->call_lock);
+ return (0);
+}
+
+/*
* SMBUS API FUNCTIONS
*
* Called from ig4iic_pci_attach/detach()
@@ -549,9 +781,9 @@
IG4_CTL_RESTARTEN |
IG4_CTL_SPEED_STD);
- sc->smb = device_add_child(sc->dev, "smbus", -1);
- if (sc->smb == NULL) {
- device_printf(sc->dev, "smbus driver not found\n");
+ sc->iicbus = device_add_child(sc->dev, "iicbus", -1);
+ if (sc->iicbus == NULL) {
+ device_printf(sc->dev, "iicbus driver not found\n");
error = ENXIO;
goto done;
}
@@ -624,15 +856,15 @@
if (error)
return (error);
}
- if (sc->smb)
- device_delete_child(sc->dev, sc->smb);
+ if (sc->iicbus)
+ device_delete_child(sc->dev, sc->iicbus);
if (sc->intr_handle)
bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle);
sx_xlock(&sc->call_lock);
mtx_lock(&sc->io_lock);
- sc->smb = NULL;
+ sc->iicbus = NULL;
sc->intr_handle = NULL;
reg_write(sc, IG4_REG_INTR_MASK, 0);
set_controller(sc, 0);
@@ -976,4 +1208,4 @@
}
#undef REGDUMP
-DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);
+DRIVER_MODULE(iicbus, ig4iic, iicbus_driver, iicbus_devclass, NULL, NULL);
Index: sys/dev/ichiic/ig4_pci.c
===================================================================
--- sys/dev/ichiic/ig4_pci.c
+++ sys/dev/ichiic/ig4_pci.c
@@ -60,6 +60,7 @@
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <dev/smbus/smbconf.h>
+#include <dev/iicbus/iiconf.h>
#include "smbus_if.h"
@@ -180,6 +181,10 @@
DEVMETHOD(smbus_bread, ig4iic_smb_bread),
DEVMETHOD(smbus_trans, ig4iic_smb_trans),
+ DEVMETHOD(iicbus_transfer, ig4iic_transfer),
+ DEVMETHOD(iicbus_reset, ig4iic_reset),
+ DEVMETHOD(iicbus_callback, iicbus_null_callback),
+
DEVMETHOD_END
};
@@ -191,7 +196,9 @@
static devclass_t ig4iic_pci_devclass;
-DRIVER_MODULE(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0);
+DRIVER_MODULE_ORDERED(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0,
+ SI_ORDER_ANY);
MODULE_DEPEND(ig4iic, pci, 1, 1, 1);
MODULE_DEPEND(ig4iic, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_DEPEND(ig4iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
MODULE_VERSION(ig4iic, 1);
Index: sys/dev/ichiic/ig4_var.h
===================================================================
--- sys/dev/ichiic/ig4_var.h
+++ sys/dev/ichiic/ig4_var.h
@@ -42,6 +42,7 @@
#include "device_if.h"
#include "pci_if.h"
#include "smbus_if.h"
+#include "iicbus_if.h"
#define IG4_RBUFSIZE 128
#define IG4_RBUFMASK (IG4_RBUFSIZE - 1)
@@ -51,7 +52,7 @@
struct ig4iic_softc {
device_t dev;
struct intr_config_hook enum_hook;
- device_t smb;
+ device_t iicbus;
struct resource *regs_res;
int regs_rid;
struct resource *intr_res;
@@ -115,5 +116,7 @@
extern smbus_bwrite_t ig4iic_smb_bwrite;
extern smbus_bread_t ig4iic_smb_bread;
extern smbus_trans_t ig4iic_smb_trans;
+extern iicbus_transfer_t ig4iic_transfer;
+extern iicbus_reset_t ig4iic_reset;
#endif
Index: sys/dev/isl/isl.c
===================================================================
--- sys/dev/isl/isl.c
+++ sys/dev/isl/isl.c
@@ -52,14 +52,12 @@
#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/systm.h>
-#include <sys/uio.h>
-#include <sys/vnode.h>
-#include <dev/smbus/smbconf.h>
-#include <dev/smbus/smbus.h>
+#include <dev/iicbus/iiconf.h>
+#include <dev/iicbus/iicbus.h>
#include <dev/isl/isl.h>
-#include "smbus_if.h"
+#include "iicbus_if.h"
#include "bus_if.h"
#include "device_if.h"
@@ -71,46 +69,58 @@
struct isl_softc {
device_t dev;
- int addr;
-
struct sx isl_sx;
};
/* Returns < 0 on problem. */
-static int isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask);
+static int isl_read_sensor(device_t dev, uint8_t cmd_mask);
+
+static int
+isl_read_byte(device_t dev, uint8_t reg, uint8_t *val)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR | IIC_M_NOSTOP, 1, &reg },
+ { addr, IIC_M_RD, 1, val },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
+
+static int
+isl_write_byte(device_t dev, uint8_t reg, uint8_t val)
+{
+ uint16_t addr = iicbus_get_addr(dev);
+ uint8_t bytes[] = { reg, val };
+ struct iic_msg msgs[] = {
+ { addr, IIC_M_WR, nitems(bytes), bytes },
+ };
+
+ return (iicbus_transfer(dev, msgs, nitems(msgs)));
+}
/*
* Initialize the device
*/
static int
-init_device(device_t dev, int addr, int probe)
+init_device(device_t dev, int probe)
{
- static char bl_init[] = { 0x00 };
-
- device_t bus;
int error;
- bus = device_get_parent(dev); /* smbus */
-
/*
* init procedure: send 0x00 to test ref and cmd reg 1
*/
- error = smbus_trans(bus, addr, REG_TEST,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_init, sizeof(bl_init), NULL, 0, NULL);
+ error = isl_write_byte(dev, REG_TEST, 0);
if (error)
goto done;
-
- error = smbus_trans(bus, addr, REG_CMD1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- bl_init, sizeof(bl_init), NULL, 0, NULL);
+ error = isl_write_byte(dev, REG_CMD1, 0);
if (error)
goto done;
pause("islinit", hz/100);
done:
- if (error)
+ if (error && !probe)
device_printf(dev, "Unable to initialize\n");
return (error);
}
@@ -138,27 +148,33 @@
sizeof(struct isl_softc),
};
+#if 0
+static void
+isl_identify(driver_t *driver, device_t parent)
+{
+
+ if (device_find_child(parent, "asl", -1)) {
+ if (bootverbose)
+ printf("asl: device(s) already created\n");
+ return;
+ }
+
+ /* Check if we can communicate to our slave. */
+ if (init_device(dev, 0x88, 1) == 0)
+ BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "isl", -1);
+}
+#endif
+
static int
isl_probe(device_t dev)
{
- int addr;
- int error;
-
- addr = smbus_get_addr(dev);
+ uint32_t addr = iicbus_get_addr(dev);
- /*
- * 0x44 - isl ambient light sensor on the acer c720.
- * (other devices might use other ids).
- */
- if (addr != 0x44)
+ if (addr != 0x88)
return (ENXIO);
-
- error = init_device(dev, addr, 1);
- if (error)
+ if (init_device(dev, 1) != 0)
return (ENXIO);
-
device_set_desc(dev, "ISL Digital Ambient Light Sensor");
-
return (BUS_PROBE_VENDOR);
}
@@ -168,36 +184,28 @@
struct isl_softc *sc;
struct sysctl_ctx_list *sysctl_ctx;
struct sysctl_oid *sysctl_tree;
- int addr;
int use_als;
int use_ir;
int use_prox;
sc = device_get_softc(dev);
+ sc->dev = dev;
- if (!sc)
- return (ENOMEM);
-
- addr = smbus_get_addr(dev);
-
- if (init_device(dev, addr, 0))
+ if (init_device(dev, 0) != 0)
return (ENXIO);
sx_init(&sc->isl_sx, "ISL read lock");
- sc->dev = dev;
- sc->addr = addr;
-
sysctl_ctx = device_get_sysctl_ctx(dev);
sysctl_tree = device_get_sysctl_tree(dev);
- use_als = isl_read_sensor(dev, addr, CMD1_MASK_ALS_ONCE) >= 0;
- use_ir = isl_read_sensor(dev, addr, CMD1_MASK_IR_ONCE) >= 0;
- use_prox = isl_read_sensor(dev, addr, CMD1_MASK_PROX_ONCE) >= 0;
+ use_als = isl_read_sensor(dev, CMD1_MASK_ALS_ONCE) >= 0;
+ use_ir = isl_read_sensor(dev, CMD1_MASK_IR_ONCE) >= 0;
+ use_prox = isl_read_sensor(dev, CMD1_MASK_PROX_ONCE) >= 0;
if (use_als) {
SYSCTL_ADD_PROC(sysctl_ctx,
- SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
+ SYSCTL_CHILDREN(sysctl_tree), OID_AUTO,
"als", CTLTYPE_INT | CTLFLAG_RD,
sc, ISL_METHOD_ALS, isl_sysctl, "I",
"Current ALS sensor read-out");
@@ -252,7 +260,6 @@
static int ranges[] = { 1000, 4000, 16000, 64000};
struct isl_softc *sc;
- device_t bus;
uint8_t rbyte;
int arg;
int resolution;
@@ -262,10 +269,7 @@
arg = -1;
sx_xlock(&sc->isl_sx);
- bus = device_get_parent(sc->dev); /* smbus */
- if (smbus_trans(bus, sc->addr, REG_CMD2,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(sc->dev, REG_CMD2, &rbyte) != 0) {
sx_xunlock(&sc->isl_sx);
return (-1);
}
@@ -275,16 +279,14 @@
switch (oidp->oid_arg2) {
case ISL_METHOD_ALS:
- arg = (isl_read_sensor(sc->dev, sc->addr,
+ arg = (isl_read_sensor(sc->dev,
CMD1_MASK_ALS_ONCE) * range) >> resolution;
break;
case ISL_METHOD_IR:
- arg = isl_read_sensor(sc->dev, sc->addr,
- CMD1_MASK_IR_ONCE);
+ arg = isl_read_sensor(sc->dev, CMD1_MASK_IR_ONCE);
break;
case ISL_METHOD_PROX:
- arg = isl_read_sensor(sc->dev, sc->addr,
- CMD1_MASK_PROX_ONCE);
+ arg = isl_read_sensor(sc->dev, CMD1_MASK_PROX_ONCE);
break;
case ISL_METHOD_RESOLUTION:
arg = (1 << resolution);
@@ -300,18 +302,13 @@
}
static int
-isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask)
+isl_read_sensor(device_t dev, uint8_t cmd_mask)
{
- device_t bus;
uint8_t rbyte;
uint8_t cmd;
int ret;
- bus = device_get_parent(dev); /* smbus */
-
- if (smbus_trans(bus, addr, REG_CMD1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(dev, REG_CMD1, &rbyte) != 0) {
device_printf(dev,
"Couldn't read first byte before issuing command %d\n",
cmd_mask);
@@ -319,27 +316,21 @@
}
cmd = (rbyte & 0x1f) | cmd_mask;
- if (smbus_trans(bus, addr, REG_CMD1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- &cmd, sizeof(cmd), NULL, 0, NULL)) {
+ if (isl_write_byte(dev, REG_CMD1, cmd) != 0) {
device_printf(dev, "Couldn't write command %d\n", cmd_mask);
return (-1);
}
pause("islconv", hz/10);
- if (smbus_trans(bus, addr, REG_DATA1,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(dev, REG_DATA1, &rbyte) != 0) {
device_printf(dev,
"Couldn't read first byte after command %d\n", cmd_mask);
return (-1);
}
ret = rbyte;
- if (smbus_trans(bus, addr, REG_DATA2,
- SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
- NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ if (isl_read_byte(dev, REG_DATA2, &rbyte) != 0) {
device_printf(dev, "Couldn't read second byte after command %d\n", cmd_mask);
return (-1);
}
@@ -348,6 +339,6 @@
return (ret);
}
-DRIVER_MODULE(isl, smbus, isl_driver, isl_devclass, NULL, NULL);
-MODULE_DEPEND(isl, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+DRIVER_MODULE(isl, iicbus, isl_driver, isl_devclass, NULL, NULL);
+MODULE_DEPEND(isl, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);
MODULE_VERSION(isl, 1);
Index: sys/modules/i2c/controllers/ichiic/Makefile
===================================================================
--- sys/modules/i2c/controllers/ichiic/Makefile
+++ sys/modules/i2c/controllers/ichiic/Makefile
@@ -2,7 +2,7 @@
.PATH: ${.CURDIR}/../../../../dev/ichiic
KMOD = ig4
-SRCS = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \
+SRCS = device_if.h bus_if.h iicbus_if.h pci_if.h smbus_if.h \
ig4_iic.c ig4_pci.c ig4_reg.h ig4_var.h
.include <bsd.kmod.mk>
Index: sys/modules/i2c/cyapa/Makefile
===================================================================
--- sys/modules/i2c/cyapa/Makefile
+++ sys/modules/i2c/cyapa/Makefile
@@ -2,6 +2,6 @@
.PATH: ${.CURDIR}/../../../dev/cyapa
KMOD = cyapa
-SRCS = cyapa.c device_if.h bus_if.h smbus_if.h vnode_if.h
+SRCS = cyapa.c device_if.h bus_if.h iicbus_if.h vnode_if.h
.include <bsd.kmod.mk>
Index: sys/modules/i2c/isl/Makefile
===================================================================
--- sys/modules/i2c/isl/Makefile
+++ sys/modules/i2c/isl/Makefile
@@ -2,6 +2,6 @@
.PATH: ${.CURDIR}/../../../dev/isl
KMOD = isl
-SRCS = isl.c device_if.h bus_if.h smbus_if.h vnode_if.h
+SRCS = isl.c device_if.h bus_if.h iicbus_if.h
.include <bsd.kmod.mk>

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 11:25 AM (14 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31973892
Default Alt Text
D8172.id21134.diff (29 KB)

Event Timeline