Module Name:    src
Committed By:   jakllsch
Date:           Thu Aug  4 01:48:34 UTC 2011

Modified Files:
        src/sys/dev/i2c: files.i2c
Added Files:
        src/sys/dev/i2c: cx24227.c cx24227var.h

Log Message:
Add Conexant/Samsung CX24227/S5H1409 demodulator subroutines.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/dev/i2c/cx24227.c src/sys/dev/i2c/cx24227var.h
cvs rdiff -u -r1.39 -r1.40 src/sys/dev/i2c/files.i2c

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.39 src/sys/dev/i2c/files.i2c:1.40
--- src/sys/dev/i2c/files.i2c:1.39	Thu Aug  4 01:45:37 2011
+++ src/sys/dev/i2c/files.i2c	Thu Aug  4 01:48:34 2011
@@ -1,4 +1,4 @@
-#	$NetBSD: files.i2c,v 1.39 2011/08/04 01:45:37 jakllsch Exp $
+#	$NetBSD: files.i2c,v 1.40 2011/08/04 01:48:34 jakllsch Exp $
 
 defflag	opt_i2cbus.h				I2C_SCAN
 define	i2cbus { }
@@ -42,6 +42,10 @@
 define	mt2131: i2cexec
 file	dev/i2c/mt2131.c			mt2131
 
+# Conexant/Samsung CX24227/S5H1409 demodulator
+define	cx24227: i2cexec
+file	dev/i2c/cx24227.c			cx24227
+
 #
 # I2C master devices
 #

Added files:

Index: src/sys/dev/i2c/cx24227.c
diff -u /dev/null src/sys/dev/i2c/cx24227.c:1.1
--- /dev/null	Thu Aug  4 01:48:34 2011
+++ src/sys/dev/i2c/cx24227.c	Thu Aug  4 01:48:34 2011
@@ -0,0 +1,307 @@
+/* $NetBSD: cx24227.c,v 1.1 2011/08/04 01:48:34 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2008, 2011 Jonathan A. Kollasch
+ * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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: cx24227.c,v 1.1 2011/08/04 01:48:34 jakllsch Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kmem.h>
+
+#include <dev/i2c/cx24227var.h>
+
+struct cx24227 {
+	device_t        parent;
+	i2c_tag_t       tag;
+	i2c_addr_t      addr;
+};
+
+static int cx24227_writereg(struct cx24227 *, uint8_t, uint16_t);
+static int cx24227_readreg(struct cx24227 *, uint8_t, uint16_t *);
+
+static int cx24227_init(struct cx24227 *);
+
+static struct documentation_wanted {
+	uint8_t		r;
+	uint16_t	v;
+} documentation_wanted[] = {
+	{ 0x00, 0x0071, },
+	{ 0x01, 0x3213, },
+	{ 0x09, 0x0025, },
+	{ 0x1c, 0x001d, },
+	{ 0x1f, 0x002d, },
+	{ 0x20, 0x001d, },
+	{ 0x22, 0x0022, },
+	{ 0x23, 0x0020, },
+	{ 0x29, 0x110f, },
+	{ 0x2a, 0x10b4, },
+	{ 0x2b, 0x10ae, },
+	{ 0x2c, 0x0031, },
+	{ 0x31, 0x010d, },
+	{ 0x32, 0x0100, },
+	{ 0x44, 0x0510, },
+	{ 0x54, 0x0104, },
+	{ 0x58, 0x2222, },
+	{ 0x59, 0x1162, },
+	{ 0x5a, 0x3211, },
+	{ 0x5d, 0x0370, },
+	{ 0x5e, 0x0296, },
+	{ 0x61, 0x0010, },
+	{ 0x63, 0x4a00, },
+	{ 0x65, 0x0800, },
+	{ 0x71, 0x0003, },
+	{ 0x72, 0x0470, },
+	{ 0x81, 0x0002, },
+	{ 0x82, 0x0600, },
+	{ 0x86, 0x0002, },
+	{ 0x8a, 0x2c38, },
+	{ 0x8b, 0x2a37, },
+	{ 0x92, 0x302f, },
+	{ 0x93, 0x3332, },
+	{ 0x96, 0x000c, },
+	{ 0x99, 0x0101, },
+	{ 0x9c, 0x2e37, },
+	{ 0x9d, 0x2c37, },
+	{ 0x9e, 0x2c37, },
+	{ 0xab, 0x0100, },
+	{ 0xac, 0x1003, },
+	{ 0xad, 0x103f, },
+	{ 0xe2, 0x0100, },
+	{ 0xe3, 0x1000, },
+	{ 0x28, 0x1010, },
+	{ 0xb1, 0x000e, },
+};
+
+
+static int
+cx24227_writereg(struct cx24227 *sc, uint8_t reg, uint16_t data)
+{
+	int error;
+	uint8_t r[3];
+
+	if (iic_acquire_bus(sc->tag, I2C_F_POLL) != 0)
+		return false;
+
+	r[0] = reg;
+	r[1] = (data >> 8) & 0xff;
+	r[2] = data & 0xff;
+	error = iic_exec(sc->tag, I2C_OP_WRITE_WITH_STOP, sc->addr,
+	    r, 3, NULL, 0, I2C_F_POLL);
+	
+	iic_release_bus(sc->tag, I2C_F_POLL);
+
+	return error;
+}
+
+static int
+cx24227_readreg(struct cx24227 *sc, uint8_t reg, uint16_t *data)
+{
+	int error;
+	uint8_t r[2];
+
+	if (iic_acquire_bus(sc->tag, I2C_F_POLL) != 0)
+		return -1;
+
+	*data = 0x0000;
+
+	error = iic_exec(sc->tag, I2C_OP_READ_WITH_STOP, sc->addr,
+			 &reg, 1, r, 2, I2C_F_POLL);
+
+	iic_release_bus(sc->tag, I2C_F_POLL);
+
+	*data |= r[0] << 8;
+	*data |= r[1];
+
+	return error;
+}
+
+uint16_t
+cx24227_get_signal(struct cx24227 *sc)
+{
+	uint16_t sig = 0;
+
+	cx24227_readreg(sc, 0xf1, &sig);
+	
+	return sig;
+}
+
+fe_status_t
+cx24227_get_dtv_status(struct cx24227 *sc)
+{
+	uint16_t reg;
+	fe_status_t status = 0;
+
+	cx24227_readreg(sc, 0xf1, &reg);
+
+	if(reg & 0x1000)
+		status = FE_HAS_VITERBI | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+	if(reg & 0x8000)
+		status |= FE_HAS_LOCK | FE_HAS_SYNC;
+
+	return status;
+}
+
+int
+cx24227_set_modulation(struct cx24227 *sc, fe_modulation_t modulation)
+{
+	printf("%s\n", __func__);
+
+	/* soft reset */
+	cx24227_writereg(sc, 0xf5, 0x0000);
+	cx24227_writereg(sc, 0xf5, 0x0001);
+
+	/* 8 VSB */
+	cx24227_writereg(sc, 0xf4, 0x0000);
+
+	/* soft reset */
+	cx24227_writereg(sc, 0xf5, 0x0000);
+	cx24227_writereg(sc, 0xf5, 0x0001);
+
+#if 0
+	delay(100);
+
+	/* open the i2c gate */
+	cx24227_writereg(sc, 0xf3, 0x0001);
+
+	/* we could tune in here? */
+
+	/* close the i2c gate */
+	cx24227_writereg(sc, 0xf3, 0x0000);
+
+#endif
+	return 0;
+}
+
+void
+cx24227_enable(struct cx24227* sc, bool enable)
+{
+	if (enable == true) {
+		cx24227_init(sc);
+	}
+}
+
+struct cx24227 *
+cx24227_open(device_t parent, i2c_tag_t tag, i2c_addr_t addr)
+{
+	struct cx24227 *sc;
+	int e;
+	uint16_t value;
+
+	sc = kmem_alloc(sizeof(*sc), KM_SLEEP);
+	if (sc == NULL)
+		return NULL;
+
+	sc->parent = parent;
+	sc->tag = tag;
+	sc->addr = addr;
+
+	/* read chip ids */
+	value = 0;
+	e = cx24227_readreg(sc, 0x04, &value);
+	printf("%s chipid %04x\n", __func__, value);
+
+	if (e) {
+		printf("%s read failed %d\n", __func__, e);
+		kmem_free(sc, sizeof(*sc));
+		return NULL;
+	}
+
+	value = 0x0001; /* open the i2c gate */
+	e = cx24227_writereg(sc, 0xf3, value);
+#if 0
+	if (e) {
+		printf("%s write failed %d\n", __func__, e);
+		kmem_free(sc, sizeof(*sc));
+		return NULL;
+	}
+#endif
+
+	cx24227_init(sc);
+
+	return sc;
+}
+
+void
+cx24227_close(struct cx24227 *sc)
+{
+	kmem_free(sc, sizeof(*sc));
+}
+
+
+static void
+cx24227_sleepreset(struct cx24227 *sc)
+{
+	cx24227_writereg(sc, 0xf2, 0);
+	cx24227_writereg(sc, 0xfa, 0);
+}
+
+static int
+cx24227_init(struct cx24227 *sc)
+{
+	int i;
+	uint16_t reg;
+
+	cx24227_sleepreset(sc);
+
+	for(i = 0; i < __arraycount(documentation_wanted); i++)
+		cx24227_writereg(sc, documentation_wanted[i].r, documentation_wanted[i].v);
+
+	/* Serial */
+	cx24227_readreg(sc, 0xab, &reg);
+	reg |= 0x0100;
+	cx24227_writereg(sc, 0xab, reg);
+
+	/* no spectral inversion */
+	cx24227_writereg(sc, 0x1b, 0x0110);
+
+	/* 44MHz IF */
+	cx24227_writereg(sc, 0x87, 0x01be);
+	cx24227_writereg(sc, 0x88, 0x0436);
+	cx24227_writereg(sc, 0x89, 0x054d);
+
+	/* GPIO on */
+	cx24227_readreg(sc, 0xe3, &reg);
+	reg |= 0x1100;
+	cx24227_writereg(sc, 0xe3, reg);
+
+	/* clocking */
+	cx24227_readreg(sc, 0xac, &reg);
+	reg &= ~0x3000;
+	reg |= 0x1000;
+	cx24227_writereg(sc, 0xac, reg);
+
+	/* soft reset */
+	cx24227_writereg(sc, 0xf5, 0x0000);
+	cx24227_writereg(sc, 0xf5, 0x0001);
+	
+	/* open gate */
+	cx24227_writereg(sc, 0xf3, 0x0001);
+
+	return 0;
+}
Index: src/sys/dev/i2c/cx24227var.h
diff -u /dev/null src/sys/dev/i2c/cx24227var.h:1.1
--- /dev/null	Thu Aug  4 01:48:34 2011
+++ src/sys/dev/i2c/cx24227var.h	Thu Aug  4 01:48:34 2011
@@ -0,0 +1,45 @@
+/* $NetBSD: cx24227var.h,v 1.1 2011/08/04 01:48:34 jakllsch Exp $ */
+
+/*
+ * Copyright (c) 2011 Jonathan A. Kollasch
+ * 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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_CX24227VAR_H_
+#define _DEV_I2C_CX24227VAR_H_
+
+#include <dev/i2c/i2cvar.h>
+#include <dev/dtv/dtvio.h>
+
+struct cx24227;
+
+struct cx24227 * cx24227_open(device_t, i2c_tag_t, i2c_addr_t);
+void cx24227_close(struct cx24227 *);
+void cx24227_enable(struct cx24227 *, bool);
+int cx24227_set_modulation(struct cx24227 *, fe_modulation_t);
+fe_status_t cx24227_get_dtv_status(struct cx24227 *);
+uint16_t cx24227_get_signal(struct cx24227 *);
+uint16_t cx24227_get_snr(struct cx24227 *);
+
+#endif /* _DEV_I2C_CX24227VAR_H_ */

Reply via email to