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 <a...@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 a...@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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to