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, + ®, 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, ®); + + 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 |= 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 |= 0x1100; + cx24227_writereg(sc, 0xe3, reg); + + /* clocking */ + cx24227_readreg(sc, 0xac, ®); + 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_ */