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, &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 @@ 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 *)&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 @@ 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, &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)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-stable-11 mailing list