Module Name:    src
Committed By:   khorben
Date:           Thu May 16 15:36:50 UTC 2013

Modified Files:
        src/sys/dev/i2c [khorben-n900]: files.i2c
Added Files:
        src/sys/dev/i2c [khorben-n900]: lp5523.c lp5523reg.h

Log Message:
Initial import of the lp5523led(4) driver, a programmable 9-output LED
driver from Texas Instruments. This is not functional yet, but exposes
sysctl nodes and the internal temperature sensor (not refreshed at the
moment).

Tested on my Nokia N900 smartphone.


To generate a diff of this commit:
cvs rdiff -u -r1.49.2.3 -r1.49.2.4 src/sys/dev/i2c/files.i2c
cvs rdiff -u -r0 -r1.1.2.1 src/sys/dev/i2c/lp5523.c \
    src/sys/dev/i2c/lp5523reg.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/i2c/files.i2c
diff -u src/sys/dev/i2c/files.i2c:1.49.2.3 src/sys/dev/i2c/files.i2c:1.49.2.4
--- src/sys/dev/i2c/files.i2c:1.49.2.3	Sun May 12 01:49:44 2013
+++ src/sys/dev/i2c/files.i2c	Thu May 16 15:36:50 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: files.i2c,v 1.49.2.3 2013/05/12 01:49:44 khorben Exp $
+#	$NetBSD: files.i2c,v 1.49.2.4 2013/05/16 15:36:50 khorben Exp $
 
 obsolete defflag	opt_i2cbus.h		I2C_SCAN
 define	i2cbus { }
@@ -187,3 +187,7 @@ device	mcp980x: sysmon_envsys
 attach	mcp980x at iic
 file	dev/i2c/mcp980x.c 		mcp980x
 
+# TI LP5523 LED driver
+device	lp5523led: sysmon_envsys
+attach	lp5523led at iic
+file	dev/i2c/lp5523.c		lp5523led

Added files:

Index: src/sys/dev/i2c/lp5523.c
diff -u /dev/null src/sys/dev/i2c/lp5523.c:1.1.2.1
--- /dev/null	Thu May 16 15:36:50 2013
+++ src/sys/dev/i2c/lp5523.c	Thu May 16 15:36:50 2013
@@ -0,0 +1,255 @@
+/* $NetBSD: lp5523.c,v 1.1.2.1 2013/05/16 15:36:50 khorben Exp $ */
+
+/*
+ * Texas Instruments LP5523 Programmable 9-Output LED Driver
+ *
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Pierre Pronchery (khor...@defora.org).
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
+__KERNEL_RCSID(0, "$NetBSD: lp5523.c,v 1.1.2.1 2013/05/16 15:36:50 khorben Exp $");
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/sysctl.h>
+
+#include <dev/sysmon/sysmonvar.h>
+
+#include <dev/i2c/i2cvar.h>
+
+#include <dev/i2c/lp5523reg.h>
+
+#define LP5523_DEGC2UK(t) ((t * 1000000) + 273150000)
+
+/* constants */
+enum lp5523_leds {
+	LP5523_LED_0 = 0,
+	LP5523_LED_1,
+	LP5523_LED_2,
+	LP5523_LED_3,
+	LP5523_LED_4,
+	LP5523_LED_5,
+	LP5523_LED_6,
+	LP5523_LED_7,
+	LP5523_LED_8
+};
+#define LP5523_LED_LAST		LP5523_LED_8
+#define LP5523_LED_CNT		(LP5523_LED_LAST + 1)
+
+/* variables */
+struct lp5523_softc {
+	device_t		sc_dev;
+	i2c_tag_t		sc_i2c;
+	i2c_addr_t		sc_addr;
+
+	struct sysctllog	*sc_sysctllog;
+
+	/* temperature sensor */
+	struct sysmon_envsys	*sc_sme;
+	envsys_data_t		sc_temp_sensor;
+};
+
+static int	lp5523_match(device_t, cfdata_t, void *);
+static void	lp5523_attach(device_t, device_t, void *);
+static void	lp5523_attach_envsys(struct lp5523_softc *);
+static void	lp5523_attach_sysctl(struct lp5523_softc *);
+
+static int	lp5523_reset(struct lp5523_softc *);
+
+static int	lp5523_sysctl(SYSCTLFN_ARGS);
+
+static int	lp5523_read_1(struct lp5523_softc *, uint8_t, uint8_t *);
+static int	lp5523_write_1(struct lp5523_softc *, uint8_t, uint8_t);
+
+CFATTACH_DECL_NEW(lp5523led, sizeof(struct lp5523_softc),
+	lp5523_match, lp5523_attach, NULL, NULL);
+
+static int
+lp5523_match(device_t parent, cfdata_t match, void *aux)
+{
+	return 1;
+}
+
+static void
+lp5523_attach(device_t parent, device_t self, void *aux)
+{
+	struct lp5523_softc *sc = device_private(self);
+	struct i2c_attach_args *ia = aux;
+
+	sc->sc_dev = self;
+	sc->sc_i2c = ia->ia_tag;
+	sc->sc_addr = ia->ia_addr;
+
+	lp5523_reset(sc);
+
+	aprint_normal(": LED driver\n");
+	aprint_naive(": LED driver\n");
+
+	lp5523_attach_sysctl(sc);
+
+	lp5523_attach_envsys(sc);
+
+	if (!pmf_device_register(sc->sc_dev, NULL, NULL)) {
+		aprint_error_dev(sc->sc_dev,
+		    "could not establish power handler\n");
+	}
+}
+
+static void
+lp5523_attach_envsys(struct lp5523_softc *sc)
+{
+	const int flags = ENVSYS_FMONNOTSUPP | ENVSYS_FHAS_ENTROPY
+		| ENVSYS_FVALID_MIN | ENVSYS_FVALID_MAX;
+	int8_t s8;
+
+	sc->sc_sme = sysmon_envsys_create();
+
+	sc->sc_sme->sme_cookie = sc;
+	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
+	sc->sc_sme->sme_flags = SME_DISABLE_REFRESH;
+
+	sc->sc_temp_sensor.flags = flags;
+	sc->sc_temp_sensor.units = ENVSYS_STEMP;
+	sc->sc_temp_sensor.state = ENVSYS_SINVALID;
+	sc->sc_temp_sensor.value_min = LP5523_DEGC2UK(-41);
+	sc->sc_temp_sensor.value_max = LP5523_DEGC2UK(89);
+
+	strlcat(sc->sc_temp_sensor.desc, "temperature",
+			sizeof(sc->sc_temp_sensor.desc));
+
+	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_temp_sensor) != 0
+			|| sysmon_envsys_register(sc->sc_sme) != 0)
+	{
+		aprint_error_dev(sc->sc_dev, "unable to attach the temperature"
+				" sensor\n");
+		sysmon_envsys_destroy(sc->sc_sme);
+		sc->sc_sme = NULL;
+		return;
+	}
+
+	iic_acquire_bus(sc->sc_i2c, 0);
+	lp5523_read_1(sc, LP5523_REG_TEMP_READ, &s8);
+	iic_release_bus(sc->sc_i2c, 0);
+	if (s8 >= -41 && s8 <= 89) {
+		sc->sc_temp_sensor.state = ENVSYS_SVALID;
+		sc->sc_temp_sensor.value_cur = LP5523_DEGC2UK(s8);
+	}
+}
+
+static void
+lp5523_attach_sysctl(struct lp5523_softc *sc)
+{
+	struct sysctllog **log = &sc->sc_sysctllog;
+	const struct sysctlnode *rnode, *cnode;
+	unsigned int i;
+	char buf[8];
+	int error;
+
+	error = sysctl_createv(log, 0, NULL, &rnode, CTLFLAG_PERMANENT,
+			CTLTYPE_NODE, "hw", NULL, NULL, 0, NULL, 0, CTL_HW,
+			CTL_EOL);
+	if (error)
+		return;
+
+	error = sysctl_createv(log, 0, &rnode, &rnode, CTLFLAG_PERMANENT,
+			CTLTYPE_NODE, device_xname(sc->sc_dev),
+			SYSCTL_DESCR("lp5523led control"), NULL, 0, NULL, 0,
+			CTL_CREATE, CTL_EOL);
+	if (error)
+		return;
+
+	for (i = 0; i < LP5523_LED_CNT; i++) {
+		snprintf(buf, sizeof(buf), "led%u", i);
+		error = sysctl_createv(log, 0, &rnode, &cnode,
+				CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+				CTLTYPE_INT, buf, SYSCTL_DESCR("LED enable"),
+				lp5523_sysctl, 0, (void *)sc, 0, CTL_CREATE,
+				CTL_EOL);
+		if (error)
+			break;
+	}
+}
+
+static int
+lp5523_reset(struct lp5523_softc *sc)
+{
+	uint8_t u8;
+
+	iic_acquire_bus(sc->sc_i2c, 0);
+	lp5523_write_1(sc, LP5523_REG_RESET, 0xff);
+
+	u8 = LP5523_REG_ENGINE_CNTRL1_CHIP_EN;
+	lp5523_write_1(sc, LP5523_REG_ENGINE_CNTRL1, u8);
+	iic_release_bus(sc->sc_i2c, 0);
+
+	return 0;
+}
+
+static int
+lp5523_sysctl(SYSCTLFN_ARGS)
+{
+	struct lp5523_softc *sc;
+	struct sysctlnode node;
+	u_int led;
+	int error;
+
+	node = *rnode;
+	sc = node.sysctl_data;
+	iic_acquire_bus(sc->sc_i2c, 0);
+	/* FIXME really implement */
+	led = 0;
+	iic_release_bus(sc->sc_i2c, 0);
+
+	node.sysctl_data = &led;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	iic_acquire_bus(sc->sc_i2c, 0);
+	/* FIXME really implement */
+	error = 0;
+	iic_release_bus(sc->sc_i2c, 0);
+
+	return error;
+}
+
+static int
+lp5523_read_1(struct lp5523_softc *sc, uint8_t reg, uint8_t *val)
+{
+	return iic_exec(sc->sc_i2c, I2C_OP_READ_WITH_STOP, sc->sc_addr,
+			&reg, sizeof(reg), val, sizeof(*val), 0);
+}
+
+static int
+lp5523_write_1(struct lp5523_softc *sc, uint8_t reg, uint8_t val)
+{
+	uint8_t data[2] = { reg, val };
+
+	return iic_exec(sc->sc_i2c, I2C_OP_WRITE_WITH_STOP, sc->sc_addr,
+			NULL, 0, data, sizeof(data), 0);
+}
Index: src/sys/dev/i2c/lp5523reg.h
diff -u /dev/null src/sys/dev/i2c/lp5523reg.h:1.1.2.1
--- /dev/null	Thu May 16 15:36:50 2013
+++ src/sys/dev/i2c/lp5523reg.h	Thu May 16 15:36:50 2013
@@ -0,0 +1,142 @@
+/* $NetBSD: lp5523reg.h,v 1.1.2.1 2013/05/16 15:36:50 khorben Exp $ */
+
+/*
+ * Texas Instruments LP5523 Programmable 9-Output LED Driver
+ *
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Pierre Pronchery (khor...@defora.org).
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#ifndef _DEV_I2C_LP5523REG_H_
+#define _DEV_I2C_LP5523REG_H_
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: lp5523reg.h,v 1.1.2.1 2013/05/16 15:36:50 khorben Exp $");
+
+/* registers */
+#define LP5523_REG_ENGINE_CNTRL1		0x00
+#define  LP5523_REG_ENGINE_CNTRL1_CHIP_EN	__BIT(6)
+#define  LP5523_REG_ENGINE_CNTRL1_ENGINE1_EXEC	__BITS(4,5)
+#define  LP5523_REG_ENGINE_CNTRL1_ENGINE2_EXEC	__BITS(2,3)
+#define  LP5523_REG_ENGINE_CNTRL1_ENGINE3_EXEC	__BITS(0,1)
+
+#define LP5523_REG_ENGINE_CNTRL2	0x01
+#define LP5523_REG_OUTPUT_DIRECT_MSB	0x02
+#define LP5523_REG_OUTPUT_DIRECT_LSB	0x03
+#define LP5523_REG_OUTPUT_ONOFF_MSB	0x04
+#define LP5523_REG_OUTPUT_ONOFF_LSB	0x05
+#define LP5523_REG_D1_CONTROL		0x06
+#define LP5523_REG_D2_CONTROL		0x07
+#define LP5523_REG_D3_CONTROL		0x08
+#define LP5523_REG_D4_CONTROL		0x09
+#define LP5523_REG_D5_CONTROL		0x0a
+#define LP5523_REG_D6_CONTROL		0x0b
+#define LP5523_REG_D7_CONTROL		0x0c
+#define LP5523_REG_D8_CONTROL		0x0d
+#define LP5523_REG_D9_CONTROL		0x0e
+#define LP5523_REG_D1_PWM		0x16
+#define LP5523_REG_D2_PWM		0x17
+#define LP5523_REG_D3_PWM		0x18
+#define LP5523_REG_D4_PWM		0x19
+#define LP5523_REG_D5_PWM		0x1a
+#define LP5523_REG_D6_PWM		0x1b
+#define LP5523_REG_D7_PWM		0x1c
+#define LP5523_REG_D8_PWM		0x1d
+#define LP5523_REG_D9_PWM		0x1e
+#define LP5523_REG_D1_CURRENT		0x26
+#define LP5523_REG_D2_CURRENT		0x27
+#define LP5523_REG_D3_CURRENT		0x28
+#define LP5523_REG_D4_CURRENT		0x29
+#define LP5523_REG_D5_CURRENT		0x2a
+#define LP5523_REG_D6_CURRENT		0x2b
+#define LP5523_REG_D7_CURRENT		0x2c
+#define LP5523_REG_D8_CURRENT		0x2d
+#define LP5523_REG_D9_CURRENT		0x2e
+#define LP5523_REG_MISC			0x36
+#define LP5523_REG_ENGINE1_PC		0x37
+#define LP5523_REG_ENGINE2_PC		0x38
+#define LP5523_REG_ENGINE3_PC		0x39
+#define LP5523_REG_STATUS		0x3a
+#define LP5523_REG_GPO			0x3b
+#define LP5523_REG_VARIABLE		0x3c
+#define LP5523_REG_RESET		0x3d
+#define LP5523_REG_TEMP_ADC		0x3e
+#define LP5523_REG_TEMP_READ		0x3f
+#define LP5523_REG_TEMP_WRITE		0x40
+#define LP5523_REG_LED_TEST		0x41
+#define LP5523_REG_TEST_ADC		0x42
+#define LP5523_REG_ENGINE1_VARA		0x45
+#define LP5523_REG_ENGINE2_VARA		0x46
+#define LP5523_REG_ENGINE3_VARA		0x47
+#define LP5523_REG_MASTER_FADER1	0x48
+#define LP5523_REG_MASTER_FADER2	0x49
+#define LP5523_REG_MASTER_FADER3	0x4a
+#define LP5523_REG_ENG1_PROG_START	0x4c
+#define LP5523_REG_ENG2_PROG_START	0x4d
+#define LP5523_REG_ENG3_PROG_START	0x4e
+#define LP5523_REG_PROG_MEM_PAGE_SEL	0x4f
+#define LP5523_REG_PROGRAM_MEMORY_08	0x50
+#define LP5523_REG_PROGRAM_MEMORY_00	0x51
+#define LP5523_REG_PROGRAM_MEMORY_18	0x52
+#define LP5523_REG_PROGRAM_MEMORY_10	0x53
+#define LP5523_REG_PROGRAM_MEMORY_28	0x54
+#define LP5523_REG_PROGRAM_MEMORY_20	0x55
+#define LP5523_REG_PROGRAM_MEMORY_38	0x56
+#define LP5523_REG_PROGRAM_MEMORY_30	0x57
+#define LP5523_REG_PROGRAM_MEMORY_48	0x58
+#define LP5523_REG_PROGRAM_MEMORY_40	0x59
+#define LP5523_REG_PROGRAM_MEMORY_58	0x5a
+#define LP5523_REG_PROGRAM_MEMORY_50	0x5b
+#define LP5523_REG_PROGRAM_MEMORY_68	0x5c
+#define LP5523_REG_PROGRAM_MEMORY_60	0x5d
+#define LP5523_REG_PROGRAM_MEMORY_78	0x5e
+#define LP5523_REG_PROGRAM_MEMORY_70	0x5f
+#define LP5523_REG_PROGRAM_MEMORY_88	0x60
+#define LP5523_REG_PROGRAM_MEMORY_80	0x61
+#define LP5523_REG_PROGRAM_MEMORY_98	0x62
+#define LP5523_REG_PROGRAM_MEMORY_90	0x63
+#define LP5523_REG_PROGRAM_MEMORY_A8	0x64
+#define LP5523_REG_PROGRAM_MEMORY_A0	0x65
+#define LP5523_REG_PROGRAM_MEMORY_B8	0x66
+#define LP5523_REG_PROGRAM_MEMORY_B0	0x67
+#define LP5523_REG_PROGRAM_MEMORY_C8	0x68
+#define LP5523_REG_PROGRAM_MEMORY_C0	0x69
+#define LP5523_REG_PROGRAM_MEMORY_D8	0x6a
+#define LP5523_REG_PROGRAM_MEMORY_D0	0x6b
+#define LP5523_REG_PROGRAM_MEMORY_E8	0x6c
+#define LP5523_REG_PROGRAM_MEMORY_E0	0x6d
+#define LP5523_REG_PROGRAM_MEMORY_F8	0x6e
+#define LP5523_REG_PROGRAM_MEMORY_F0	0x6f
+#define LP5523_REG_ENG1_MAPPING_MSB	0x70
+#define LP5523_REG_ENG1_MAPPING_LSB	0x71
+#define LP5523_REG_ENG2_MAPPING_MSB	0x72
+#define LP5523_REG_ENG2_MAPPING_LSB	0x73
+#define LP5523_REG_ENG3_MAPPING_MSB	0x74
+#define LP5523_REG_ENG3_MAPPING_LSB	0x75
+#define LP5523_REG_GAIN_CHANGE_CTRL	0x76
+
+#endif  /* _DEV_I2C_LP5523REG_H_ */

Reply via email to