Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148492738
D2811.id7183.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
16 KB
Referenced Files
None
Subscribers
None
D2811.id7183.diff
View Options
Index: share/man/man4/Makefile
===================================================================
--- share/man/man4/Makefile
+++ share/man/man4/Makefile
@@ -200,6 +200,7 @@
iicbus.4 \
iicsmb.4 \
iir.4 \
+ isl.4 \
inet.4 \
inet6.4 \
intpm.4 \
Index: share/man/man4/isl.4
===================================================================
--- /dev/null
+++ share/man/man4/isl.4
@@ -0,0 +1,98 @@
+.\" Copyright (c) 2015 Michael Gmelin <freebsd@grem.de>
+.\" 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 July 22, 2015
+.Dt ISL 4
+.Os
+.Sh NAME
+.Nm isl
+.Nd Intersil(TM) I2C ISL29018 sensor 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 isl"
+.Cd "device ig4"
+.Cd "device smbus"
+.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
+isl_load="YES"
+ig4_load="YES"
+.Ed
+.Sh DESCRIPTION
+The
+.Nm
+driver provides access to sensor data provided by the Intersil(TM) I2C
+ISL29018 Digital Ambient Light Sensor and Proximity Sensor with Interrupt
+Function.
+Functionality is basic and provided through the
+.Xr sysctl 8
+interface.
+.Sh SYSCTL VARIABLES
+The following
+.Xr sysctl 8
+variables are available:
+.Bl -tag -width "dev.isl.X.resolution"
+.It Va dev.isl.X.als
+Current ALS (Ambient Light Sensor) readout.
+.It Va dev.isl.X.ir
+Current IR (InfraRed) sensor readout.
+.It Va dev.isl.X.prox
+Current proximity sensor readout.
+.It Va dev.isl.X.resolution
+Current sensor resolution.
+.It Va dev.isl.X.range
+Current sensor range.
+.El
+.Sh EXAMPLES
+.Ss Ambient light sensor read out
+.Bd -literal
+$ sysctl dev.isl.0.als
+dev.isl.0.als: 64
+.Ed
+.Ss Automatically adjust brightness
+This requires the port
+.Pa graphics/intel-backlight
+and only works with laptops using a supported Intel(R) GPU.
+.Bd -literal
+$ pkg install intel-backlight
+$ sh /usr/local/share/examples/intel-backlight/isl_backlight.sh
+.Ed
+.Sh SEE ALSO
+.Xr ig4 4 ,
+.Xr smbus 4
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Michael Gmelin Aq Mt freebsd@grem.de .
+.Pp
+This manual page was written by
+.An Michael Gmelin Aq Mt freebsd@grem.de .
Index: sys/dev/isl/isl.h
===================================================================
--- /dev/null
+++ sys/dev/isl/isl.h
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2015 Michael Gmelin <freebsd@grem.de>
+ * 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$
+ */
+
+#ifndef _ISL_H_
+#define _ISL_H_
+
+/* Command register 1 (bits 7-5) */
+#define REG_CMD1 0x00
+#define CMD1_MASK_POWER_DOWN 0x00 /* 00000000 */
+#define CMD1_MASK_ALS_ONCE 0x01 << 5 /* 00100000 */
+#define CMD1_MASK_IR_ONCE 0x02 << 5 /* 01000000 */
+#define CMD1_MASK_PROX_ONCE 0x03 << 5 /* 01100000 */
+/* RESERVED */ /* 10000000 */
+#define CMD1_MASK_ALS_CONT 0x05 << 5 /* 10100000 */
+#define CMD1_MASK_IR_CONT 0x06 << 5 /* 11000000 */
+#define CMD1_MASK_PROX_CONT 0x07 << 5 /* 11100000 */
+
+/* Command register 2 (bits) */
+#define REG_CMD2 0x01
+
+/* data registers */
+#define REG_DATA1 0x02
+#define REG_DATA2 0x03
+#define CMD2_SHIFT_RANGE 0x00
+#define CMD2_MASK_RANGE (0x03 << CMD2_SHIFT_RANGE)
+#define CMD2_SHIFT_RESOLUTION 0x02
+#define CMD2_MASK_RESOLUTION (0x03 << CMD2_SHIFT_RESOLUTION)
+
+/* Interrupt registers */
+#define REG_INT_LO_LSB 0x04
+#define REG_INT_LO_MSB 0x05
+#define REG_INT_HI_LSB 0x06
+#define REG_INT_HI_MSB 0x07
+
+/* Test register (should hold 0x00 at all times */
+#define REG_TEST 0x08
+
+#endif
Index: sys/dev/isl/isl.c
===================================================================
--- /dev/null
+++ sys/dev/isl/isl.c
@@ -0,0 +1,379 @@
+/*-
+ * Copyright (c) 2015 Michael Gmelin <freebsd@grem.de>
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Driver for intersil I2C ISL29018 Digital Ambient Light Sensor and Proximity
+ * Sensor with Interrupt Function, only tested connected over SMBus (ig4iic).
+ *
+ * Datasheet:
+ * http://www.intersil.com/en/products/optoelectronics/ambient-light-and-proximity-sensors/light-to-digital-sensors/ISL29018.html
+ * http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29018.pdf
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/sysctl.h>
+#include <sys/mbuf.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/lockmgr.h>
+#include <sys/sx.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/vnode.h>
+#include <sys/event.h>
+
+#include <dev/smbus/smbconf.h>
+#include <dev/smbus/smbus.h>
+#include "isl.h"
+
+#include "smbus_if.h"
+#include "bus_if.h"
+#include "device_if.h"
+
+#define ISL_METHOD_ALS 0x10
+#define ISL_METHOD_IR 0x11
+#define ISL_METHOD_PROX 0x12
+#define ISL_METHOD_RESOLUTION 0x13
+#define ISL_METHOD_RANGE 0x14
+
+struct isl_softc {
+ device_t dev;
+ int unit;
+ int addr;
+
+ struct sx isl_sx;
+ struct cdev* devnode;
+ struct sysctl_ctx_list* sysctl_ctx;
+ struct sysctl_oid* sysctl_tree;
+};
+
+/* Returns < 0 on problem. */
+static int isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask);
+
+/*
+ * Initialize the device
+ */
+static
+int
+init_device(device_t dev, int addr, int probe)
+{
+ static char bl_init[] = { 0x00 };
+
+ device_t bus;
+ int error;
+
+ bus = device_get_parent(dev); /* smbus */
+
+ /*
+ * init procedure: send 0x00 to test ref and cmd reg 1
+ */
+ error = smbus_trans(bus, addr, REG_TEST,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ bl_init, sizeof(bl_init), NULL, 0, NULL);
+ if (error)
+ goto done;
+
+ error = smbus_trans(bus, addr, REG_CMD1,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ bl_init, sizeof(bl_init), NULL, 0, NULL);
+ if (error)
+ goto done;
+
+ pause("islinit", hz);
+
+done:
+ if (error)
+ device_printf(dev, "Unable to initialize\n");
+ return (error);
+}
+
+static int isl_probe(device_t);
+static int isl_attach(device_t);
+static int isl_detach(device_t);
+
+static int isl_sysctl(SYSCTL_HANDLER_ARGS);
+
+static devclass_t isl_devclass;
+
+static device_method_t isl_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, isl_probe),
+ DEVMETHOD(device_attach, isl_attach),
+ DEVMETHOD(device_detach, isl_detach),
+
+ DEVMETHOD_END
+};
+
+static driver_t isl_driver = {
+ "isl",
+ isl_methods,
+ sizeof(struct isl_softc),
+};
+
+static struct cdevsw isl_cdevsw = {
+ .d_version = D_VERSION
+};
+
+static int
+isl_probe(device_t dev)
+{
+ device_t bus;
+ int unit;
+ int addr;
+ int error;
+ int dummy = 0;
+
+ bus = device_get_parent(dev); /* smbus */
+
+ if (!bus)
+ return (ENXIO);
+
+ addr = smbus_get_addr(dev);
+
+ /*
+ * Only match against specific addresses to avoid blowing up
+ * other I2C devices. At least for now.
+ *
+ * 0x44 - isl ambient light sensor on the acer c720.
+ */
+ if (addr != 0x44)
+ return (ENXIO);
+
+ unit = device_get_unit(dev);
+ tsleep(&dummy, 0, "islstab", hz);
+
+ error = init_device(dev, addr, 1);
+ if (error)
+ return (ENXIO);
+
+ device_set_desc(dev, "ISL Digital Ambient Light Sensor");
+
+ return (BUS_PROBE_VENDOR);
+}
+
+static int
+isl_attach(device_t dev)
+{
+ struct isl_softc *sc = device_get_softc(dev);
+ unsigned char* addr_ptr;
+ int unit;
+ int addr;
+
+ if (!sc)
+ return (ENOMEM);
+
+ bzero(sc, sizeof(*sc));
+
+ sx_init(&sc->isl_sx, "ISL read lock");
+
+ unit = device_get_unit(dev);
+ addr_ptr = device_get_ivars(dev);
+
+ if (!addr_ptr) {
+ printf("No address ptr set\n");
+ return (ENXIO);
+ }
+
+ addr = *addr_ptr;
+
+ if (init_device(dev, addr, 0))
+ return (ENXIO);
+
+ sc->dev = dev;
+ sc->unit = unit;
+ sc->addr = addr;
+
+ sc->sysctl_ctx = device_get_sysctl_ctx(dev);
+ sc->sysctl_tree = device_get_sysctl_tree(dev);
+
+ if (isl_read_sensor(dev, addr, CMD1_MASK_ALS_ONCE) >= 0) {
+ SYSCTL_ADD_PROC(sc->sysctl_ctx,
+ SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+ "als", CTLTYPE_INT | CTLFLAG_RD,
+ sc, ISL_METHOD_ALS, isl_sysctl, "I",
+ "Current ALS sensor read-out");
+ }
+
+ if (isl_read_sensor(dev, addr, CMD1_MASK_IR_ONCE) >= 0) {
+ SYSCTL_ADD_PROC(sc->sysctl_ctx,
+ SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+ "ir", CTLTYPE_INT | CTLFLAG_RD,
+ sc, ISL_METHOD_IR, isl_sysctl, "I",
+ "Current IR sensor read-out");
+ }
+
+ if (isl_read_sensor(dev, addr, CMD1_MASK_PROX_ONCE) >= 0) {
+ SYSCTL_ADD_PROC(sc->sysctl_ctx,
+ SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+ "prox", CTLTYPE_INT | CTLFLAG_RD,
+ sc, ISL_METHOD_PROX, isl_sysctl, "I",
+ "Current proximity sensor read-out");
+ }
+
+ SYSCTL_ADD_PROC(sc->sysctl_ctx,
+ SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+ "resolution", CTLTYPE_INT | CTLFLAG_RD,
+ sc, ISL_METHOD_RESOLUTION, isl_sysctl, "I",
+ "Current proximity sensor resolution");
+
+ SYSCTL_ADD_PROC(sc->sysctl_ctx,
+ SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO,
+ "range", CTLTYPE_INT | CTLFLAG_RD,
+ sc, ISL_METHOD_RANGE, isl_sysctl, "I",
+ "Current proximity sensor range");
+
+ sc->devnode = make_dev(&isl_cdevsw, unit,
+ UID_ROOT, GID_WHEEL, 0600, "isl%d", unit);
+
+ sc->devnode->si_drv1 = sc;
+
+ return (0);
+}
+
+static int
+isl_detach(device_t dev)
+{
+ struct isl_softc *sc = device_get_softc(dev);
+
+ if (sc->devnode)
+ destroy_dev(sc->devnode);
+
+ sx_destroy(&sc->isl_sx);
+
+ return (0);
+}
+
+static int
+isl_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ struct isl_softc *sc = (struct isl_softc *)oidp->oid_arg1;
+ device_t bus;
+ uint8_t rbyte;
+ int arg = -1;
+ static int resolutions[] = { 16, 12, 8, 4};
+ static int ranges[] = { 1000, 4000, 16000, 64000};
+ int resolution;
+ int range;
+
+ sx_xlock(&sc->isl_sx);
+ bus = device_get_parent(sc->dev); /* smbus */
+ if (smbus_trans(bus, sc->addr, REG_CMD2,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ sx_xunlock(&sc->isl_sx);
+ return (-1);
+ }
+ resolution = resolutions[(rbyte & CMD2_MASK_RESOLUTION)
+ >> CMD2_SHIFT_RESOLUTION];
+ range = ranges[(rbyte & CMD2_MASK_RANGE) >> CMD2_SHIFT_RANGE];
+
+ switch (oidp->oid_arg2) {
+ case ISL_METHOD_ALS:
+ arg = (isl_read_sensor(sc->dev, sc->addr,
+ CMD1_MASK_ALS_ONCE) * range) >> resolution;
+ break;
+ case ISL_METHOD_IR:
+ arg = isl_read_sensor(sc->dev, sc->addr,
+ CMD1_MASK_IR_ONCE);
+ break;
+ case ISL_METHOD_PROX:
+ arg = isl_read_sensor(sc->dev, sc->addr,
+ CMD1_MASK_PROX_ONCE);
+ break;
+ case ISL_METHOD_RESOLUTION:
+ arg = (1 << resolution);
+ break;
+ case ISL_METHOD_RANGE:
+ arg = range;
+ break;
+ }
+ sx_xunlock(&sc->isl_sx);
+
+ SYSCTL_OUT(req, &arg, sizeof(arg));
+ return (0);
+}
+
+static int isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask)
+{
+ device_t bus;
+ uint8_t rbyte;
+ uint8_t cmd;
+ int ret;
+
+ bus = device_get_parent(dev); /* smbus */
+
+ if (smbus_trans(bus, addr, REG_CMD1,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ device_printf(dev,
+ "Couldn't read first byte before issuing command %d\n",
+ cmd_mask);
+ return (-1);
+ }
+
+ cmd = (rbyte & 0x1f) | cmd_mask;
+ if (smbus_trans(bus, addr, REG_CMD1,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ &cmd, sizeof(cmd), NULL, 0, NULL)) {
+ device_printf(dev, "Couldn't write command %d\n", cmd_mask);
+ return (-1);
+ }
+
+ pause("islconv", hz/10);
+
+ if (smbus_trans(bus, addr, REG_DATA1,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ device_printf(dev,
+ "Couldn't read first byte after command %d\n", cmd_mask);
+ return (-1);
+ }
+
+ ret = rbyte;
+ if (smbus_trans(bus, addr, REG_DATA2,
+ SMB_TRANS_NOCNT | SMB_TRANS_7BIT,
+ NULL, 0, &rbyte, sizeof(rbyte), NULL)) {
+ device_printf(dev, "Couldn't read second byte after command %d\n", cmd_mask);
+ return (-1);
+ }
+ ret += rbyte << 8;
+
+ return (ret);
+}
+
+DRIVER_MODULE(isl, smbus, isl_driver, isl_devclass, NULL, NULL);
+MODULE_DEPEND(isl, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER);
+MODULE_VERSION(isl, 1);
Index: sys/modules/i2c/Makefile
===================================================================
--- sys/modules/i2c/Makefile
+++ sys/modules/i2c/Makefile
@@ -1,6 +1,6 @@
# $FreeBSD$
SUBDIR =
-SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic smb
+SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic smb isl
.include <bsd.subdir.mk>
Index: sys/modules/i2c/isl/Makefile
===================================================================
--- /dev/null
+++ sys/modules/i2c/isl/Makefile
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+.PATH: ${.CURDIR}/../../../dev/isl
+KMOD = isl
+SRCS = isl.c device_if.h bus_if.h smbus_if.h vnode_if.h
+
+.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 19, 5:57 AM (15 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29950447
Default Alt Text
D2811.id7183.diff (16 KB)
Attached To
Mode
D2811: New driver for intersil I2C ISL29018 Digital Ambient Light Sensor
Attached
Detach File
Event Timeline
Log In to Comment