svn commit: r310072 - in stable/11: . share/man/man4 sys/conf sys/dev/chromebook_platform sys/dev/cyapa sys/dev/ichiic sys/dev/iicbus sys/dev/isl sys/modules sys/modules/chromebook_platform sys/mod...
Andriy Gapon
avg at FreeBSD.org
Wed Dec 14 16:27:31 UTC 2016
Author: avg
Date: Wed Dec 14 16:27:28 2016
New Revision: 310072
URL: https://svnweb.freebsd.org/changeset/base/310072
Log:
MFC r308104: add iic interface to ig4 driver, move isl and cyapa to iicbus
Added:
stable/11/share/man/man4/chromebook_platform.4
- copied unchanged from r308104, head/share/man/man4/chromebook_platform.4
stable/11/sys/dev/chromebook_platform/
- copied from r308104, head/sys/dev/chromebook_platform/
stable/11/sys/modules/chromebook_platform/
- copied from r308104, head/sys/modules/chromebook_platform/
Modified:
stable/11/UPDATING
stable/11/share/man/man4/cyapa.4
stable/11/share/man/man4/ig4.4
stable/11/share/man/man4/isl.4
stable/11/sys/conf/files
stable/11/sys/dev/cyapa/cyapa.c
stable/11/sys/dev/ichiic/ig4_iic.c
stable/11/sys/dev/ichiic/ig4_pci.c
stable/11/sys/dev/ichiic/ig4_var.h
stable/11/sys/dev/iicbus/iicbus.c
stable/11/sys/dev/isl/isl.c
stable/11/sys/modules/Makefile
stable/11/sys/modules/i2c/controllers/ichiic/Makefile
stable/11/sys/modules/i2c/cyapa/Makefile
stable/11/sys/modules/i2c/isl/Makefile
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/UPDATING
==============================================================================
--- stable/11/UPDATING Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/UPDATING Wed Dec 14 16:27:28 2016 (r310072)
@@ -16,6 +16,12 @@ from older versions of FreeBSD, try WITH
the tip of head, and then rebuild without this option. The bootstrap process
from older version of current across the gcc/clang cutover is a bit fragile.
+20161030:
+ isl(4) and cyapa(4) drivers now require a new driver,
+ chromebook_platform(4), to work properly on Chromebook-class hardware.
+ On other types of hardware the drivers may need to be configured using
+ device hints. Please see the corresponding manual pages for details.
+
20161210:
Relocatable object files with the extension of .So have been renamed
to use an extension of .pico instead. The purpose of this change is
Copied: stable/11/share/man/man4/chromebook_platform.4 (from r308104, head/share/man/man4/chromebook_platform.4)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/11/share/man/man4/chromebook_platform.4 Wed Dec 14 16:27:28 2016 (r310072, copy of r308104, head/share/man/man4/chromebook_platform.4)
@@ -0,0 +1,68 @@
+.\" Copyright (c) 2016 Andriy Gapon <avg at FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd October 13, 2016
+.Dt CHROMEBOOK_PLATFORM 4
+.Os
+.Sh NAME
+.Nm chromebook_platform
+.Nd support driver for hardware on various Chromebook models
+.Sh SYNOPSIS
+To compile this driver into the kernel, place the following lines into
+the kernel configuration file:
+.Bd -ragged -offset indent
+.Cd "device chromebook_platform"
+.Ed
+.Pp
+Alternatively, to load the driver as a module at boot time, place the following line in
+.Xr loader.conf 5 :
+.Bd -literal -offset indent
+chromebook_platform_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides automatic configuration for devices that cannot be enumerated
+or safely probed.
+In particular, I2C peripherals are different from model to model.
+.Nm
+has a model-specific information about the I2C peripherals, their drivers,
+their bus attachments and slave addresses.
+.Pp
+Note that
+.Nm
+does not load driver modules for the peripherals.
+Those have to be compiled into the kernel or loaded separately.
+.Sh SEE ALSO
+.Xr cyapa 4 ,
+.Xr iicbus 4 ,
+.Xr isl 4 ,
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver and this manual page were written by
+.An Andriy Gapon Aq Mt avg at FreeBSD.org .
Modified: stable/11/share/man/man4/cyapa.4
==============================================================================
--- stable/11/share/man/man4/cyapa.4 Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/share/man/man4/cyapa.4 Wed Dec 14 16:27:28 2016 (r310072)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2015
+.Dd October 03, 2016
.Dt CYAPA 4
.Os
.Sh NAME
@@ -36,7 +36,7 @@ the kernel configuration file:
.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 @@ Alternatively, to load the driver as a m
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,20 @@ The upper right corner issues a MIDDLE b
The lower right corner issues a RIGHT button.
Optionally, tap to click can be enabled (see below).
.El
+.Pp
+On a system using
+.Xr device.hints 5 ,
+these values are configurable for
+.Nm :
+.Bl -tag -width "hint.cyapa.%d.addr"
+.It Va hint.cyapa.%d.at
+target
+.Xr iicbus 4 .
+.It Va hint.cyapa.%d.addr
+.Nm
+i2c address on the
+.Xr iicbus 4 .
+.El
.Sh SYSCTL VARIABLES
These
.Xr sysctl 8
@@ -175,7 +196,7 @@ file:
.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 +216,6 @@ This manual page was written by
.Sh BUGS
The
.Nm
-driver detects the device based on its I2C address (0x67).
+driver detects the device from the I2C address.
This might have unforeseen consequences if the initialization sequence
is sent to an unknown device at that address.
Modified: stable/11/share/man/man4/ig4.4
==============================================================================
--- stable/11/share/man/man4/ig4.4 Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/share/man/man4/ig4.4 Wed Dec 14 16:27:28 2016 (r310072)
@@ -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 @@ ig4_load="YES"
.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 @@ These
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 zero-based bit mask.
+When any of the bits are set, a register dump is printed for
+every I2C transfer on an
+.Nm
+device with the same unit number.
.El
.Sh SEE ALSO
-.Xr smb 4 ,
-.Xr smbus 4
+.Xr iic 4 ,
+.Xr iicbus 4
.Sh AUTHORS
.An -nosplit
The
Modified: stable/11/share/man/man4/isl.4
==============================================================================
--- stable/11/share/man/man4/isl.4 Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/share/man/man4/isl.4 Wed Dec 14 16:27:28 2016 (r310072)
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 25, 2015
+.Dd October 03, 2016
.Dt ISL 4
.Os
.Sh NAME
@@ -36,7 +36,7 @@ the kernel configuration file:
.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 @@ Alternatively, to load the driver as a m
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,20 @@ Function.
Functionality is basic and provided through the
.Xr sysctl 8
interface.
+.Pp
+On a system using
+.Xr device.hints 5 ,
+these values are configurable for
+.Nm :
+.Bl -tag -width "hint.isl.%d.addr"
+.It Va hint.isl.%d.at
+target
+.Xr iicbus 4 .
+.It Va hint.isl.%d.addr
+.Nm
+i2c address on the
+.Xr iicbus 4 .
+.El
.Sh SYSCTL VARIABLES
The following
.Xr sysctl 8
@@ -86,7 +107,7 @@ $ sh /usr/local/share/examples/intel-bac
.Ed
.Sh SEE ALSO
.Xr ig4 4 ,
-.Xr smbus 4
+.Xr iicbus 4
.Sh AUTHORS
.An -nosplit
The
@@ -99,6 +120,6 @@ This manual page was written by
.Sh BUGS
The
.Nm
-driver detects the device based on its I2C address (0x44).
+driver detects the device based from the I2C address.
This might have unforeseen consequences if the initialization sequence
is sent to an unknown device at that address.
Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/conf/files Wed Dec 14 16:27:28 2016 (r310072)
@@ -1222,6 +1222,7 @@ dev/cfi/cfi_bus_nexus.c optional cfi
dev/cfi/cfi_core.c optional cfi
dev/cfi/cfi_dev.c optional cfi
dev/cfi/cfi_disk.c optional cfid
+dev/chromebook_platform/chromebook_platform.c optional chromebook_platform
dev/ciss/ciss.c optional ciss
dev/cm/smc90cx6.c optional cm
dev/cmx/cmx.c optional cmx
@@ -1362,7 +1363,7 @@ t6fw.fw optional cxgbe \
dev/cy/cy.c optional cy
dev/cy/cy_isa.c optional cy isa
dev/cy/cy_pci.c optional cy pci
-dev/cyapa/cyapa.c optional cyapa smbus
+dev/cyapa/cyapa.c optional cyapa iicbus
dev/dc/if_dc.c optional dc pci
dev/dc/dcphy.c optional dc pci
dev/dc/pnphy.c optional dc pci
@@ -1613,8 +1614,8 @@ dev/hptiop/hptiop.c optional hptiop scb
dev/hwpmc/hwpmc_logging.c optional hwpmc
dev/hwpmc/hwpmc_mod.c optional hwpmc
dev/hwpmc/hwpmc_soft.c optional hwpmc
-dev/ichiic/ig4_iic.c optional ig4 smbus
-dev/ichiic/ig4_pci.c optional ig4 pci smbus
+dev/ichiic/ig4_iic.c optional ig4 iicbus
+dev/ichiic/ig4_pci.c optional ig4 pci iicbus
dev/ichsmb/ichsmb.c optional ichsmb
dev/ichsmb/ichsmb_pci.c optional ichsmb pci
dev/ida/ida.c optional ida
@@ -1710,7 +1711,7 @@ dev/iscsi_initiator/isc_soc.c optional i
dev/iscsi_initiator/isc_sm.c optional iscsi_initiator scbus
dev/iscsi_initiator/isc_subr.c optional iscsi_initiator scbus
dev/ismt/ismt.c optional ismt
-dev/isl/isl.c optional isl smbus
+dev/isl/isl.c optional isl iicbus
dev/isp/isp.c optional isp
dev/isp/isp_freebsd.c optional isp
dev/isp/isp_library.c optional isp
Modified: stable/11/sys/dev/cyapa/cyapa.c
==============================================================================
--- stable/11/sys/dev/cyapa/cyapa.c Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/dev/cyapa/cyapa.c Wed Dec 14 16:27:28 2016 (r310072)
@@ -122,11 +122,11 @@ __FBSDID("$FreeBSD$");
#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_fifo {
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 @@ static int cyapa_reset = 0;
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, ® },
+ { 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, ® },
+ { 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 @@ cyapa_notify(struct cyapa_softc *sc)
* 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 @@ init_device(device_t dev, struct cyapa_c
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 @@ init_device(device_t dev, struct cyapa_c
/* 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 @@ init_device(device_t dev, struct cyapa_c
/* 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 @@ init_device(device_t dev, struct cyapa_c
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 @@ cyapa_probe(device_t dev)
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 @@ cyapa_attach(device_t dev)
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 @@ cyapa_poll_thread(void *arg)
{
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 @@ cyapa_poll_thread(void *arg)
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 *)®s, sizeof(regs), NULL);
+ error = cyapa_read_bytes(sc->dev, CMD_DEV_STATUS,
+ (void *)®s, sizeof(regs));
if (error == 0) {
isidle = cyapa_raw_input(sc, ®s, freq);
}
@@ -1200,9 +1210,9 @@ cyapa_poll_thread(void *arg)
(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 @@ cyapa_set_power_mode(struct cyapa_softc
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 @@ cyapa_fuzz(int delta, int *fuzzp)
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);
Modified: stable/11/sys/dev/ichiic/ig4_iic.c
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_iic.c Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/dev/ichiic/ig4_iic.c Wed Dec 14 16:27:28 2016 (r310072)
@@ -61,6 +61,8 @@ __FBSDID("$FreeBSD$");
#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 @@ set_controller(ig4iic_softc_t *sc, uint3
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 @@ wait_status(ig4iic_softc_t *sc, uint32_t
u_int count_us = 0;
u_int limit_us = 25000; /* 25ms */
- error = SMB_ETIMEOUT;
+ error = IIC_ETIMEOUT;
for (;;) {
/*
@@ -484,6 +486,236 @@ done:
}
/*
+ * 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 explicitly send a start or stop.
+ * They are automatically sent (or not sent, depending on the
+ * configuration) when a data byte is transferred.
+ * 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 sent 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 @@ ig4iic_attach(ig4iic_softc_t *sc)
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 @@ ig4iic_detach(ig4iic_softc_t *sc)
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 @@ ig4iic_dump(ig4iic_softc_t *sc)
}
#undef REGDUMP
-DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL);
+DRIVER_MODULE(iicbus, ig4iic, iicbus_driver, iicbus_devclass, NULL, NULL);
Modified: stable/11/sys/dev/ichiic/ig4_pci.c
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_pci.c Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/dev/ichiic/ig4_pci.c Wed Dec 14 16:27:28 2016 (r310072)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
#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 @@ static device_method_t ig4iic_pci_method
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 driver_t ig4iic_pci_driver = {
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);
Modified: stable/11/sys/dev/ichiic/ig4_var.h
==============================================================================
--- stable/11/sys/dev/ichiic/ig4_var.h Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/dev/ichiic/ig4_var.h Wed Dec 14 16:27:28 2016 (r310072)
@@ -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 @@ enum ig4_op { IG4_IDLE, IG4_READ, IG4_WR
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_pcall_t ig4iic_smb_pcall
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
Modified: stable/11/sys/dev/iicbus/iicbus.c
==============================================================================
--- stable/11/sys/dev/iicbus/iicbus.c Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/dev/iicbus/iicbus.c Wed Dec 14 16:27:28 2016 (r310072)
@@ -208,7 +208,9 @@ iicbus_write_ivar(device_t bus, device_t
default:
return (EINVAL);
case IICBUS_IVAR_ADDR:
- return (EINVAL);
+ if (devi->addr != 0)
+ return (EINVAL);
+ devi->addr = value;
case IICBUS_IVAR_NOSTOP:
devi->nostop = value;
break;
Modified: stable/11/sys/dev/isl/isl.c
==============================================================================
--- stable/11/sys/dev/isl/isl.c Wed Dec 14 16:21:10 2016 (r310071)
+++ stable/11/sys/dev/isl/isl.c Wed Dec 14 16:27:28 2016 (r310072)
@@ -52,14 +52,12 @@ __FBSDID("$FreeBSD$");
#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 @@ __FBSDID("$FreeBSD$");
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, ® },
+ { 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)
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-stable-11
mailing list