diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/common/ir-keymaps.c v4l-dvb/linux/drivers/media/common/ir-keymaps.c --- v4l-dvb.20071229/linux/drivers/media/common/ir-keymaps.c 2007-12-29 22:34:26.000000000 +0100 +++ v4l-dvb/linux/drivers/media/common/ir-keymaps.c 2007-12-31 15:03:24.000000000 +0100 @@ -1898,3 +1898,40 @@ }; EXPORT_SYMBOL_GPL(ir_codes_fusionhdtv_mce); + +IR_KEYTAB_TYPE ir_codes_videomate_s350[IR_KEYTAB_SIZE] = { + [ 0x00 ] = KEY_TV, + [ 0x01 ] = KEY_DVD, + [ 0x04 ] = KEY_RECORD, + [ 0x05 ] = KEY_VIDEO, /* TV/Video */ + [ 0x07 ] = KEY_STOP, + [ 0x08 ] = KEY_PLAYPAUSE, + [ 0x0a ] = KEY_REWIND, + [ 0x0f ] = KEY_FASTFORWARD, + [ 0x10 ] = KEY_CHANNELUP, + [ 0x12 ] = KEY_VOLUMEUP, + [ 0x13 ] = KEY_CHANNELDOWN, + [ 0x14 ] = KEY_MUTE, + [ 0x15 ] = KEY_VOLUMEDOWN, + [ 0x16 ] = KEY_1, + [ 0x17 ] = KEY_2, + [ 0x18 ] = KEY_3, + [ 0x19 ] = KEY_4, + [ 0x1a ] = KEY_5, + [ 0x1b ] = KEY_6, + [ 0x1c ] = KEY_7, + [ 0x1d ] = KEY_8, + [ 0x1e ] = KEY_9, + [ 0x1f ] = KEY_0, + [ 0x21 ] = KEY_SLEEP, + [ 0x24 ] = KEY_ZOOM, + [ 0x25 ] = KEY_LAST, /* Recall */ + [ 0x26 ] = KEY_SUBTITLE, /* CC */ + [ 0x27 ] = KEY_LANGUAGE, /* MTS */ + [ 0x29 ] = KEY_CHANNEL, /* SURF */ + [ 0x2b ] = KEY_A, + [ 0x2c ] = KEY_B, + [ 0x2f ] = KEY_SHUFFLE, /* Snapshot */ +}; + +EXPORT_SYMBOL_GPL(ir_codes_videomate_s350); diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/Kconfig v4l-dvb/linux/drivers/media/dvb/frontends/Kconfig --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/Kconfig 2007-12-29 22:34:26.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/Kconfig 2007-12-31 15:04:12.000000000 +0100 @@ -71,6 +71,13 @@ help A DVB-S tuner module. Say Y when you want to support this frontend. +config DVB_ZL10313 + tristate "Zarlink ZL10313 DVB-S demodulator" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S demodulator module. Say Y when you want to support this frontend. + comment "DVB-T (terrestrial) frontends" depends on DVB_CORE @@ -360,14 +367,19 @@ This device is only used inside a SiP called togther with a demodulator for now. -config DVB_TUNER_XC5000 - tristate "Xceive XC5000 silicon tuner" - depends on I2C +config DVB_ZL1003X + tristate "Zarlink ZL10036/ZL10038 silicon tuner" + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help - A driver for the silicon tuner XC5000 from Xceive. - This device is only used inside a SiP called togther with a - demodulator for now. + A DVB-S silicon tuner module. Say Y when you want to support this tuner. + +config DVB_ZL10039 + tristate "Zarlink ZL10039 DVB-S tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A driver for the ZL10039 DVB-S tuner from Zarlink comment "Miscellaneous devices" depends on DVB_CORE diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/Makefile v4l-dvb/linux/drivers/media/dvb/frontends/Makefile --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/Makefile 2007-12-29 22:34:26.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/Makefile 2007-12-31 15:04:12.000000000 +0100 @@ -50,4 +50,6 @@ obj-$(CONFIG_DVB_TUA6100) += tua6100.o obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o obj-$(CONFIG_DVB_S5H1409) += s5h1409.o -obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o +obj-$(CONFIG_DVB_ZL10313) += zl10313.o +obj-$(CONFIG_DVB_ZL1003X) += zl1003x.o +obj-$(CONFIG_DVB_ZL10039) += zl10039.o diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10039.c v4l-dvb/linux/drivers/media/dvb/frontends/zl10039.c --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10039.c 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl10039.c 2007-12-31 15:04:12.000000000 +0100 @@ -0,0 +1,260 @@ +/* + * Driver for Zarlink ZL10039 DVB-S tuner + * + * Copyright 2007 Jan Daniël Louw + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "zl10039.h" +#include "zl10039_priv.h" + + +static int zl10039_read(const struct zl10039_state *state, + const enum zl10039_reg_addr reg, u8 *buf, + const size_t count) +{ + struct i2c_msg msg[2]; + u8 regbuf[1] = { reg }; + int i; + + io_printk("%s\n", __FUNCTION__); + /* Write register address */ + msg[0].addr = state->config.tuner_address; + msg[0].flags = 0; + msg[0].buf = regbuf; + msg[0].len = 1; + /* Read count bytes */ + msg[1].addr = state->config.tuner_address; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + if (i2c_transfer(state->i2c, msg, 2) != 2) { + eprintk("%s: i2c read error\n", __FUNCTION__); + return -EREMOTEIO; + } + for (i = 0; i < count; i++) { + io_printk("R[%s] = 0x%x\n", zl10039_reg_names[reg + i], buf[i]); + } + return 0; /* Success */ +} + +static int zl10039_write(struct zl10039_state *state, + const enum zl10039_reg_addr reg, const u8 *src, + const size_t count) +{ + u8 buf[count + 1]; + struct i2c_msg msg; + int i; + + io_printk("%s\n", __FUNCTION__); + for (i = 0; i < count; i++) { + io_printk("W[%s] = 0x%x\n", zl10039_reg_names[reg + i], src[i]); + } + /* Write register address and data in one go */ + buf[0] = reg; + memcpy(&buf[1], src, count); + msg.addr = state->config.tuner_address; + msg.flags = 0; + msg.buf = buf; + msg.len = count + 1; + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + eprintk("%s: i2c write error\n", __FUNCTION__); + return -EREMOTEIO; + } + return 0; /* Success */ +} + +static inline int zl10039_readreg(struct zl10039_state *state, + const enum zl10039_reg_addr reg, u8 *val) +{ + return zl10039_read(state, reg, val, 1); +} + +static inline int zl10039_writereg(struct zl10039_state *state, + const enum zl10039_reg_addr reg, + const u8 val) +{ + return zl10039_write(state, reg, &val, 1); +} + +static int zl10039_init(struct dvb_frontend *fe) +{ + struct zl10039_state *state = fe->tuner_priv; + int ret; + + trace_printk("%s\n", __FUNCTION__); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + /* Reset logic */ + ret = zl10039_writereg(state, GENERAL, 0x40); + if (ret < 0) { + eprintk("Note: i2c write error normal when resetting the " + "tuner\n"); + } + /* Wake up */ + ret = zl10039_writereg(state, GENERAL, 0x01); + if (ret < 0) { + eprintk("Tuner power up failed\n"); + return ret; + } + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + return 0; +} + +static int zl10039_sleep(struct dvb_frontend *fe) +{ + struct zl10039_state *state = fe->tuner_priv; + int ret; + + trace_printk("%s\n", __FUNCTION__); + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + ret = zl10039_writereg(state, GENERAL, 0x80); + if (ret < 0) { + eprintk("Tuner sleep failed\n"); + return ret; + } + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + return 0; +} + +static int zl10039_set_params(struct dvb_frontend *fe, + struct dvb_frontend_parameters *params) +{ + struct zl10039_state *state = fe->tuner_priv; + u8 buf[6]; + u8 bf; + u32 fbw; + u32 div; + int ret; + + trace_printk("%s\n", __FUNCTION__); + params_printk("Set frequency = %d, symbol rate = %d\n", + params->frequency, params->u.qpsk.symbol_rate); + + /* Assumed 10.111 MHz crystal oscillator */ + /* Cancelled num/den 80 to prevent overflow */ + div = (params->frequency * 1000) / 126387; + fbw = (params->u.qpsk.symbol_rate * 27) / 32000; + /* Cancelled num/den 10 to prevent overflow */ + bf = ((fbw * 5088) / 1011100) - 1; + + /*PLL divider*/ + buf[0] = (div >> 8) & 0x7f; + buf[1] = (div >> 0) & 0xff; + /*Reference divider*/ + /* Select reference ratio of 80 */ + buf[2] = 0x1D; + /*PLL test modes*/ + buf[3] = 0x40; + /*RF Control register*/ + buf[4] = 0x6E; /* Bypass enable */ + /*Baseband filter cutoff */ + buf[5] = bf; + + /* Open i2c gate */ + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + /* BR = 10, Enable filter adjustment */ + ret = zl10039_writereg(state, BASE1, 0x0A); + if (ret < 0) goto error; + /* Write new config values */ + ret = zl10039_write(state, PLL0, buf, sizeof(buf)); + if (ret < 0) goto error; + /* BR = 10, Disable filter adjustment */ + ret = zl10039_writereg(state, BASE1, 0x6A); + if (ret < 0) goto error; + + zl10039_dump_registers(state); + /* Close i2c gate */ + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + return 0; +error: + eprintk("Error setting tuner\n"); + return ret; +} + +static struct dvb_tuner_ops zl10039_ops; + +struct dvb_frontend * zl10039_attach(struct dvb_frontend *fe, + const struct zl10039_config *config, struct i2c_adapter *i2c) +{ + struct zl10039_state *state = NULL; + + trace_printk("%s\n", __FUNCTION__); + state = kmalloc(sizeof(struct zl10039_state), GFP_KERNEL); + if (state == NULL) goto error; + + state->i2c = i2c; + state->config.tuner_address = config->tuner_address; + + /* Open i2c gate */ + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1); + /* check if this is a valid tuner */ + if (zl10039_readreg(state, GENERAL, &state->id) < 0) { + /* Close i2c gate */ + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + goto error; + } + /* Close i2c gate */ + if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); + + state->id = state->id & 0x0F; + switch (state->id) { + case ID_ZL10039: + strcpy(fe->ops.tuner_ops.info.name, + "Zarlink ZL10039 DVB-S tuner"); + break; + default: + eprintk("Chip ID does not match a known type\n"); + goto error; + } + memcpy(&fe->ops.tuner_ops, &zl10039_ops, sizeof(struct dvb_tuner_ops)); + fe->tuner_priv = state; + iprintk("Tuner attached @ i2c address 0x%02x\n", config->tuner_address); + return fe; +error: + kfree(state); + return NULL; +} + +static int zl10039_release(struct dvb_frontend *fe) +{ + struct zl10039_state *state = fe->tuner_priv; + + trace_printk("%s\n", __FUNCTION__); + kfree(state); + fe->tuner_priv = NULL; + return 0; +} + +static struct dvb_tuner_ops zl10039_ops = { + .release = zl10039_release, + .init = zl10039_init, + .sleep = zl10039_sleep, + .set_params = zl10039_set_params, +}; + +EXPORT_SYMBOL(zl10039_attach); + +MODULE_DESCRIPTION("Zarlink ZL10039 DVB-S tuner driver"); +MODULE_AUTHOR("Jan Daniël Louw "); +MODULE_LICENSE("GPL"); diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10039.h v4l-dvb/linux/drivers/media/dvb/frontends/zl10039.h --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10039.h 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl10039.h 2007-12-31 15:04:12.000000000 +0100 @@ -0,0 +1,46 @@ +/* + Driver for Zarlink ZL10039 DVB-S tuner + + Copyright (C) 2007 Jan Daniël Louw + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef ZL10039_H +#define ZL10039_H + +struct zl10039_config +{ + /* tuner's i2c address */ + u8 tuner_address; +}; + +#if defined(CONFIG_DVB_ZL10039) || (defined(CONFIG_DVB_ZL10039_MODULE) \ + && defined(MODULE)) +struct dvb_frontend * zl10039_attach(struct dvb_frontend *fe, + const struct zl10039_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend * zl10039_attach(struct dvb_frontend *fe, + const struct zl10039_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; +} +#endif /* CONFIG_DVB_ZL10039 */ + +#endif /* ZL10039_H */ diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10039_priv.h v4l-dvb/linux/drivers/media/dvb/frontends/zl10039_priv.h --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10039_priv.h 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl10039_priv.h 2007-12-31 15:04:12.000000000 +0100 @@ -0,0 +1,121 @@ +/* + * Driver for Zarlink ZL10039 DVB-S tuner + * + * Copyright 2007 Jan Daniël Louw + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef DVB_FRONTENDS_ZL10039_PRIV +#define DVB_FRONTENDS_ZL10039_PRIV + +/* Trace function calls */ +#define DEBUG_CALL_TRACE 0 +/* Trace read/write function calls - information overload */ +#define DEBUG_IO_TRACE 0 +/* Print register values at critical points */ +#define DEBUG_DUMP_REGISTERS 0 +/* Print important params passed to functions */ +#define DEBUG_PRINT_PARAMS 0 + +#if DEBUG_CALL_TRACE + #define trace_printk(args...) printk(KERN_DEBUG "tuner: zl10039: " args) +#else + #define trace_printk(args...) +#endif + +#if DEBUG_IO_TRACE + #define io_printk(args...) printk(KERN_DEBUG "tuner: zl10039: " args) +#else + #define io_printk(args...) +#endif + +#if DEBUG_PRINT_PARAMS + #define params_printk(args...) printk(KERN_DEBUG "tuner: zl10039: " \ + args) +#else + #define params_printk(args...) +#endif + +#define eprintk(args...) printk(KERN_ERR "tuner: zl10039: " args) +#define iprintk(args...) printk(KERN_INFO "tuner: zl10039: " args) + +enum zl10039_model_id { + ID_ZL10039 = 1 +}; + +struct zl10039_state { + struct i2c_adapter *i2c; + struct zl10039_config config; + u8 id; +}; + +enum zl10039_reg_addr { + PLL0 = 0, + PLL1, + PLL2, + PLL3, + RFFE, + BASE0, + BASE1, + BASE2, + LO0, + LO1, + LO2, + LO3, + LO4, + LO5, + LO6, + GENERAL +}; + +#if DEBUG_DUMP_REGISTERS || DEBUG_IO_TRACE +static const char *zl10039_reg_names[] = { + "PLL_0", "PLL_1", "PLL_2", "PLL_3", + "RF_FRONT_END", "BASE_BAND_0", "BASE_BAND_1", "BASE_BAND_2", + "LOCAL_OSC_0", "LOCAL_OSC_1", "LOCAL_OSC_2", "LOCAL_OSC_3", + "LOCAL_OSC_4", "LOCAL_OSC_5", "LOCAL_OSC_6", "GENERAL" +}; +#endif + +#if DEBUG_DUMP_REGISTERS +static int zl10039_read(const struct zl10039_state *state, + const enum zl10039_reg_addr reg, u8 *buf, + const size_t count); + +static void zl10039_dump_registers(const struct zl10039_state *state) +{ + u8 buf[16]; + int ret; + u8 reg; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10039_read(state, PLL0, buf, sizeof(buf)); + if (ret < 0) return; + for (reg = PLL0; reg <= GENERAL; reg += 4) { + printk(KERN_DEBUG "%03x: [%02x %13s] [%02x %13s] [%02x %13s] " + "[%02x %13s]\n", reg, buf[reg], zl10039_reg_names[reg], + buf[reg+1], zl10039_reg_names[reg+1], buf[reg+2], + zl10039_reg_names[reg+2], buf[reg+3], + zl10039_reg_names[reg+3]); + } +} +#else +static inline void zl10039_dump_registers(const struct zl10039_state *state) {} +#endif /* DEBUG_DUMP_REGISTERS */ + +#endif /* DVB_FRONTENDS_ZL10039_PRIV */ + diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl1003x.c v4l-dvb/linux/drivers/media/dvb/frontends/zl1003x.c --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl1003x.c 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl1003x.c 2008-01-13 00:50:48.000000000 +0100 @@ -0,0 +1,310 @@ +/** + * Driver for Zarlink zl1003x DVB-S silicon tuner + * + * Copyright (C) 2006,2007 Tino Reichardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + ** + * This driver is currently for these two silicon tuners: + * - zl10036 (40pin, FTA) + * - zl10038 (40pin, FTA with DVB-S2) + */ + +#include +#include +#include + +#include "zl1003x.h" + +static int debug = 0; +#define dprintk(args...) \ + do { if (debug) printk(KERN_DEBUG "zl1003x: " args); } while (0) + +struct zl1003x_priv { + int i2c_address; + struct i2c_adapter *i2c; + u32 frequency; + u8 type:3; + u8 has_loopthrough:1; +}; + +static int zl1003x_read_status(struct dvb_frontend *fe) +{ + struct zl1003x_priv *priv = fe->tuner_priv; + struct i2c_msg msg[2]; + u8 buf1[1] = { 0 }; + u8 buf2[1]; + + msg[0].addr = priv->i2c_address; + msg[0].flags = 0; + msg[0].buf = buf1; + msg[0].len = 1; + + msg[1].addr = priv->i2c_address; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf2; + msg[1].len = 1; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + if (i2c_transfer(priv->i2c, msg, 2) != 2) { + printk(KERN_ERR "%s: i2c error a addr=%02x\n", + __FUNCTION__, priv->i2c_address); + return -EIO; + } + + if (debug) + dprintk("R(status): %02x, addr=%02x\n", buf2[0], priv->i2c_address); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return buf2[0]; +} + +static int zl1003x_write(struct dvb_frontend *fe, u8 *str, u8 count) +{ + struct zl1003x_priv *priv = fe->tuner_priv; + struct i2c_msg msg[1]; + u8 reg=0; + int ret; + + + /* address validation */ + if ((str[0] & 0x80) == 0x00) reg=2; + else if ((str[0] & 0xc0) == 0x80) reg=4; + else if ((str[0] & 0xf0) == 0xc0) reg=6; + else if ((str[0] & 0xf0) == 0xd0) reg=8; + else if ((str[0] & 0xf0) == 0xe0) reg=10; + else if ((str[0] & 0xf0) == 0xf0) reg=12; + else { + printk(KERN_ERR "%s: invalid data:%02x\n", __FUNCTION__, str[0]); + return -EINVAL; + } + + msg[0].addr = priv->i2c_address; + msg[0].flags = 0; + msg[0].buf = str; + msg[0].len = count; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + + ret = i2c_transfer(priv->i2c, msg, 1); + + if (ret != 1) { + printk(KERN_ERR "%s: i2c error, ret=%d\n", __FUNCTION__, ret); + return -EIO; + } + + if (debug) { + dprintk("W(%d):", reg); + { + int i; + for (i=0; iops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return 0; +} + +static int zl1003x_release(struct dvb_frontend *fe) +{ + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + dprintk("%s\n", __FUNCTION__); + + return 0; +} + +static int zl1003x_sleep(struct dvb_frontend *fe) +{ + u8 buf[2] = { 0xf0, 0x80 }; + + dprintk("%s\n", __FUNCTION__); + + return zl1003x_write(fe, buf, 2); +} + +/** + * register map of the ZL10036/ZL10038 + * + * reg[default] content + * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8 + * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0 + * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN + * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0 + * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0 + * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0 + * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1 + * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0 + * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0 + * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE + * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 + * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL + */ + +static int zl1003x_set_params(struct dvb_frontend *fe, struct + dvb_frontend_parameters *params) +{ + struct zl1003x_priv *priv = fe->tuner_priv; + u8 br, bf, buf[12]; + u32 div, fbw; + int ret; + + dprintk("%s\n", __FUNCTION__); + dprintk("Set frequency = %d, symbol rate = %d\n", + params->frequency, params->u.qpsk.symbol_rate); + + /* assumed 10.111 MHz crystal oscillator */ + div = (params->frequency * 1000) / 90276; /* 90,27 KHz r=112 */ + fbw = (params->u.qpsk.symbol_rate * 27) / 32000; /* in KHz */ + if (fbw < 28200) { + br = 17; + } else { + br = (10111 * 63 * 1000) / (fbw * 1257); + } + bf = (fbw * br * 1257) / (10111 * 1000) - 1; + + dprintk("fbw=%d, div=%d, bf=%d br=%d\n", fbw, div, bf, br); + + /* wake up */ + buf[0] = 0xf0; /* 12: testing disabled */ + buf[1] = (br << 2); /* 13: br=x clr=0 tl=0 */ + ret = zl1003x_write(fe, buf, 2); + if (ret < 0) goto error; + + /* re-enable resistor switching */ + buf[0] = 0xc0; /* 6: rsd=0 */ + buf[1] = (bf << 1); /* 7: bf=x */ + ret = zl1003x_write(fe, buf, 2); + if (ret < 0) goto error; + + /* PLL divider and br */ + buf[0] = (div >> 8) & 0x7f; /* 2: pll */ + buf[1] = (div >> 0) & 0xff; /* 3: pll */ + buf[2] = 0xf0; /* 12: testing disabled */ + buf[3] = (br << 2); /* 13: br=x */ + + /* setting of r etc ... */ + { + u8 ba=1, bg=1, c=1; + buf[4] = 0x80 | (ba << 3) | (bg << 1); /* 4: rfg=0 ba=x bg=x */ + buf[5] = 0x1d | (c << 5); /* 5: c=x r=112(1+4+8+16) */ + buf[6] = 0xd3; /* 6: from datasheet */ + buf[7] = 0x40; /* 7: from datasheet */ + buf[8] = 0xe3; /* 10: from datasheet */ + buf[9] = 0x5b; /* 11: from datasheet */ + buf[10] = 0xe3; /* 10: from datasheet */ + buf[11] = 0xf9; /* 11: from datasheet */ + if (!priv->has_loopthrough) buf[0] |= 0x01; + ret = zl1003x_write(fe, buf, 12); + if (ret < 0) goto error; + } + + /* disable resistor switching */ + udelay(60); + buf[0] = 0xc8; /* 6: rsd=1 */ + buf[1] = (bf << 1); /* 7: bf=x */ + ret = zl1003x_write(fe, buf, 2); + if (ret < 0) goto error; + + zl1003x_read_status(fe); + + return 0; +error: + printk("error setting tuner!"); + return ret; +} + +static int zl1003x_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct zl1003x_priv *priv = fe->tuner_priv; + + *frequency = priv->frequency; + + return 0; +} + +static struct dvb_tuner_ops zl1003x_tuner_ops = { + .info = { + .name = "Zarlink ZL1003X", + .frequency_min = 950000, + .frequency_max = 2150000 + }, + .release = zl1003x_release, + .sleep = zl1003x_sleep, + .set_params = zl1003x_set_params, + .get_frequency = zl1003x_get_frequency, +}; + +struct dvb_frontend *zl1003x_attach(struct dvb_frontend *fe, + const struct zl1003x_config *config, struct i2c_adapter *i2c) +{ + struct zl1003x_priv *priv = NULL; + int ret; + + priv = kzalloc(sizeof(struct zl1003x_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->has_loopthrough = config->has_loopthrough; + priv->i2c_address = config->tuner_address; + priv->type = config->tuner_type; + priv->i2c = i2c; + + memcpy(&fe->ops.tuner_ops, &zl1003x_tuner_ops, sizeof(struct dvb_tuner_ops)); + fe->tuner_priv = priv; + + switch (priv->type) { + case ZL1003X_TYPE_ZL10036: + strcpy(fe->ops.tuner_ops.info.name, "Zarlink ZL10036"); + break; + case ZL1003X_TYPE_ZL10038: + strcpy(fe->ops.tuner_ops.info.name, "Zarlink ZL10038"); + break; + default: + printk(KERN_WARNING "%s: Warning, unsupported silicon tuner!\n", + __FUNCTION__); + goto error; + } + + ret = zl1003x_read_status(fe); + if (ret < 0) { + printk("%s: tuner initialization failed\n", __FUNCTION__); + goto error; + } + + printk("%s: tuner initialization (0x%02x) ok\n", __FUNCTION__, priv->i2c_address); + + return fe; +error: + zl1003x_release(fe); + return NULL; +} +EXPORT_SYMBOL(zl1003x_attach); + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); +MODULE_DESCRIPTION("DVB ZL1003X driver"); +MODULE_AUTHOR("Tino Reichardt"); +MODULE_LICENSE("GPL"); diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl1003x.h v4l-dvb/linux/drivers/media/dvb/frontends/zl1003x.h --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl1003x.h 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl1003x.h 2007-12-31 15:11:34.000000000 +0100 @@ -0,0 +1,57 @@ +/** + * Driver for Zarlink ZL10036 DVB-S silicon tuner + * + * Copyright (C) 2006 Tino Reichardt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License Version 2, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef DVB_ZL1003X_H +#define DVB_ZL1003X_H + +#include +#include "dvb_frontend.h" + +/** + * Attach a zl10036 tuner to the supplied frontend structure. + * + * @param fe Frontend to attach to. + * @param config configuration of tuner_address, tuner_type and so on + * @param i2c i2c adapter to use. + * @return FE pointer on success, NULL on failure. + */ + +struct zl1003x_config +{ + u8 tuner_address; + u8 tuner_type:3; + u8 has_loopthrough:1; +}; + +#define ZL1003X_TYPE_ZL10036 1 +#define ZL1003X_TYPE_ZL10038 2 + +#if defined(CONFIG_DVB_ZL1003X) || (defined(CONFIG_DVB_ZL1003X_MODULE) && defined(MODULE)) +extern struct dvb_frontend* zl1003x_attach(struct dvb_frontend *fe, + const struct zl1003x_config *config, struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend* zl1003x_attach(struct dvb_frontend *fe, + const struct zl1003x_config *config, struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; +} +#endif + +#endif /* DVB_ZL1003X_H */ diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10313.c v4l-dvb/linux/drivers/media/dvb/frontends/zl10313.c --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10313.c 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl10313.c 2008-01-12 21:27:16.000000000 +0100 @@ -0,0 +1,572 @@ +/* + * Driver for Zarlink ZL10313 DVB-S demodulator + * + * Copyright 2007 Jan Daniël Louw + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#include +#include +#include +#include +#include + +#include "dvb_frontend.h" +#include "zl10313.h" +#include "zl10313_priv.h" + + +static int zl10313_read(const struct zl10313_state *state, + const enum zl10313_reg_addr reg, + u8 *buf, const size_t count) +{ + struct i2c_msg msg[2]; + u8 regbuf[1] = { reg }; + int i; + + io_printk("%s\n", __FUNCTION__); + /* Write address to read */ + msg[0].addr = state->config->demod_address; + msg[0].flags = 0; + msg[0].buf = regbuf; + msg[0].len = 1; + /* Read count bytes */ + msg[1].addr = state->config->demod_address; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + if (i2c_transfer(state->i2c, msg, 2) != 2) { + eprintk("%s: i2c read error\n", __FUNCTION__); + return -EREMOTEIO; + } + for (i = 0; i < count; i++) { + io_printk("R[%s] = 0x%x\n", zl10313_reg_names[reg + i], buf[i]); + } + return 0; +} + +static int zl10313_write(struct zl10313_state *state, + const enum zl10313_reg_addr reg, const void *src, + const size_t count) +{ + u8 buf[count + 1]; + struct i2c_msg msg; + int i; + + io_printk("%s\n", __FUNCTION__); + for (i = 0; i < count; i++) { + io_printk("R[%s] = 0x%x\n", zl10313_reg_names[reg + i], buf[i]); + } + buf[0] = reg; + memcpy(&buf[1], src, count); + msg.addr = state->config->demod_address; + msg.flags = 0; + msg.buf = buf; + msg.len = count + 1; + + if (i2c_transfer(state->i2c, &msg, 1) != 1) { + eprintk("%s: i2c write error\n", __FUNCTION__); + return -EREMOTEIO; + } + return 0; +} + +static inline int zl10313_readreg(struct zl10313_state *state, + const enum zl10313_reg_addr reg, u8 *val) +{ + return zl10313_read(state, reg, val, 1); +} + +static inline int zl10313_writereg(struct zl10313_state *state, + const enum zl10313_reg_addr reg, const u8 val) +{ + return zl10313_write(state, reg, &val, 1); +} + +static inline u32 zl10313_div(u32 a, u32 b) +{ + return (a + (b / 2)) / b; +} + +static int zl10313_read_status(struct dvb_frontend *fe, fe_status_t *s) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 status[3]; + + trace_printk("%s\n", __FUNCTION__); + *s = 0; + ret = zl10313_read(state, QPSK_STAT_H, status, sizeof(status)); + if (ret < 0) return ret; + if (status[0] & 0xc0) + *s |= FE_HAS_SIGNAL; /* signal noise ratio */ + if (status[0] & 0x04) + *s |= FE_HAS_CARRIER; /* qpsk carrier lock */ + if (status[2] & 0x02) + *s |= FE_HAS_VITERBI; /* viterbi lock */ + if (status[2] & 0x04) + *s |= FE_HAS_SYNC; /* byte align lock */ + if (status[0] & 0x01) + *s |= FE_HAS_LOCK; /* qpsk lock */ + + return 0; +} + +/* Reports only Reed-Solomon error count (Viterbi BER) */ +/* IMPROVEMENT: Implement Viterbi error count (QPSK BER), a bit of a problem + without IRQs? */ +/* Viterbi BER = RS_BERCNT / (dt * CR * 2 * SR) */ +static int zl10313_read_ber(struct dvb_frontend *fe, u32 *ber) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 buf[3]; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_read(state, RS_BERCNT_H, buf, 3); + if (ret < 0) return ret; + *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]); + return 0; +} + +/* Signal strength a number out of 1024 */ +static int zl10313_read_signal_strength(struct dvb_frontend *fe, + u16 * signal_strength) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 buf[3]; + u16 agc; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_read(state, AGC_H, buf, sizeof(buf)); + if (ret < 0) return ret; + agc = (buf[0] << 2) | (buf[1] >> 6); + *signal_strength = agc; + return 0; +} + +/* Holds for Eb/No between 0 and 12 dB */ +static int zl10313_read_snr(struct dvb_frontend *fe, u16 *snr) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 buf[2]; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_read(state, M_SNR_H, buf, sizeof(buf)); + if (ret < 0) return ret; + *snr = (13312 - (((buf[0] & 0x7f) << 8) | buf[1])) / 683; + return 0; +} + +/* Block error rate = (ucblocks * 1632) / (dt * SR * 2 * CR) */ +static int zl10313_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 buf[2]; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_read(state, RS_UBC_H, buf, sizeof(buf)); + if (ret < 0) return ret; + *ucblocks = (buf[0] << 8) | buf[1]; + return 0; +} + +static int zl10313_get_inversion(struct zl10313_state *state, + fe_spectral_inversion_t *i) +{ + int ret; + u8 vit_mode; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_readreg(state, VIT_MODE, &vit_mode); + if (ret < 0) return ret; + *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF; + return 0; +} + +static int zl10313_get_symbol_rate(struct zl10313_state *state, u32 *sr) +{ + int ret; + u16 monitor; + u8 buf[2]; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_writereg(state, MON_CTRL, 0x03); + if (ret < 0) return ret; + ret = zl10313_read(state, MONITOR_H, buf, sizeof(buf)); + if (ret < 0) return ret; + monitor = (buf[0] << 8) | buf[1]; + /* SR = monitor * 1000000 / 1024 */ + *sr = zl10313_div(monitor * 15625, 16); + return 0; +} + +static int zl10313_get_code_rate(struct zl10313_state *state, + fe_code_rate_t *cr) +{ + const fe_code_rate_t fec_tab[8] = { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, + FEC_6_7, FEC_7_8, FEC_AUTO, FEC_AUTO }; + int ret; + u8 fec_status; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_readreg(state, FEC_STATUS, &fec_status); + if (ret < 0) return ret; + *cr = fec_tab[(fec_status >> 4) & 0x07]; + return 0; +} + +static int zl10313_get_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_get_inversion(state, &p->inversion); + if (ret < 0) return ret; + ret = zl10313_get_symbol_rate(state, &p->u.qpsk.symbol_rate); + if (ret < 0) return ret; + ret = zl10313_get_code_rate(state, &p->u.qpsk.fec_inner); + if (ret < 0) return ret; + p->frequency = state->prev_frequency; + return 0; +} + +static int zl10313_set_frontend(struct dvb_frontend *fe, + struct dvb_frontend_parameters *p) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 buf[5]; + u16 sr; + const u8 fec_tab[10] = { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, + 0x20, 0x3f, 0x3f }; + const u8 inv_tab[3] = { 0x00, 0x40, 0x80 }; + + trace_printk("%s\n", __FUNCTION__); + params_printk("Setting freq: %d, fec: %s, inversion: %s\n", + p->frequency, fec_str[p->u.qpsk.fec_inner], + inv_str[p->inversion]); + + if ((p->frequency < fe->ops.info.frequency_min) || + (p->frequency > fe->ops.info.frequency_max)) return -EINVAL; + + if ((p->inversion < INVERSION_OFF) || (p->inversion > INVERSION_AUTO)) + return -EINVAL; + + if ((p->u.qpsk.symbol_rate < fe->ops.info.symbol_rate_min) || + (p->u.qpsk.symbol_rate > fe->ops.info.symbol_rate_max)) + return -EINVAL; + + if ((p->u.qpsk.fec_inner < FEC_NONE) || + (p->u.qpsk.fec_inner > FEC_AUTO)) return -EINVAL; + + if ((p->u.qpsk.fec_inner == FEC_4_5) || + (p->u.qpsk.fec_inner == FEC_8_9)) return -EINVAL; + + /* Set the tuner up first */ + fe->ops.tuner_ops.set_params(fe, p); + + /* sr = SR * 256 / 1000000 */ + sr = zl10313_div(p->u.qpsk.symbol_rate * 4, 15625); + /* SYM_RATE */ + buf[0] = (sr >> 8) & 0x3f; + buf[1] = (sr >> 0) & 0xff; + /* VIT_MODE */ + buf[2] = inv_tab[p->inversion] | fec_tab[p->u.qpsk.fec_inner]; + /* QPSK_CTRL */ + buf[3] = 0x40; /* swap I and Q before QPSK demodulation */ + if (p->u.qpsk.symbol_rate < 10000000) + buf[3] |= 0x04; /* use afc mode */ + /* GO */ + buf[4] = 0x01; + + ret = zl10313_write(state, SYM_RATE_H, buf, sizeof(buf)); + if (ret < 0) { + eprintk("Demodulator failed setup\n"); + return ret; + } + state->prev_frequency = p->frequency; + zl10313_dump_registers(state); + + return 0; +} + +static int zl10313_sleep(struct dvb_frontend *fe) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 config; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_readreg(state, CONFIG, &config); + if (ret < 0) return ret; + /* enter standby */ + ret = zl10313_writereg(state, CONFIG, config & 0x7f); + if (ret < 0) return ret; + return 0; +} + +static int zl10313_init(struct dvb_frontend *fe) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 buf[2]; + + trace_printk("%s\n", __FUNCTION__); + /* Set up for QPSK DVB-S with 10MHz crystal ref */ + ret = zl10313_writereg(state, CONFIG, 0x8c); + if (ret < 0) return ret; + /* Wait 150 us to settle */ + udelay(150); + /* Full reset */ + ret = zl10313_writereg(state, RESET, 0x80); + if (ret < 0) return ret; + /* Crucial for correct operation - differs from mt312 datasheet */ + ret = zl10313_writereg(state, GPP_CTRL, 0x80); + if (ret < 0) return ret; + /* Crucial for correct operation - unknown register in zl10313 */ + /* Don't know what this register is for in the zl10313 */ + ret = zl10313_writereg(state, VIT_ERRPER_M, 0x00); + if (ret < 0) return ret; + buf[0] = 182; + buf[1] = zl10313_div(10111000, 88000); + /*Set DISECQ ratio for 22KHz tone */ + ret = zl10313_write(state, SYS_CLK, buf, sizeof(buf)); + if (ret < 0) return ret; + /* Supposed to set register 49 to value 50 - can't see any difference */ + ret = zl10313_writereg(state, SNR_THS_HIGH, 50); + if (ret < 0) return ret; + + zl10313_dump_registers(state); + + return 0; +} + +static int zl10313_send_master_cmd(struct dvb_frontend *fe, + struct dvb_diseqc_master_cmd *c) +{ + struct zl10313_state *state = fe->demodulator_priv; + int ret; + u8 diseqc_mode; + + trace_printk("%s\n", __FUNCTION__); + if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg))) return -EINVAL; + + ret = zl10313_readreg(state, DISEQC_MODE, &diseqc_mode); + if (ret < 0) return ret; + + ret = zl10313_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len); + if (ret < 0) return ret; + + ret = zl10313_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40) | + ((c->msg_len - 1) << 3) | 0x04); + if (ret < 0) return ret; + + msleep(100); + + /* set DISEQC_MODE[2:0] to zero if a return message is expected */ + if (c->msg[0] & 0x02) { + ret = zl10313_writereg(state, DISEQC_MODE, diseqc_mode & 0x40); + if (ret < 0) return ret; + } + return 0; +} + +static int zl10313_send_burst(struct dvb_frontend *fe, + const fe_sec_mini_cmd_t c) +{ + struct zl10313_state *state = fe->demodulator_priv; + const u8 mini_tab[2] = { 0x02, 0x03 }; + int ret; + u8 diseqc_mode; + + trace_printk("%s\n", __FUNCTION__); + params_printk("Set mini burst %s (enum %d)\n", mini_cmd_name[c], c); + if (c > SEC_MINI_B) return -EINVAL; + ret = zl10313_readreg(state, DISEQC_MODE, &diseqc_mode); + if (ret < 0) return ret; + ret = zl10313_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40) | + mini_tab[c]); + if (ret < 0) return ret; + return 0; +} + +static int zl10313_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) +{ + struct zl10313_state *state = fe->demodulator_priv; + const u8 tone_tab[2] = { 0x01, 0x00 }; + int ret; + u8 diseqc_mode; + + trace_printk("%s\n", __FUNCTION__); + params_printk("Set tone %s (enum %d)\n", tone_name[tone], tone); + if (tone > SEC_TONE_OFF) return -EINVAL; + ret = zl10313_readreg(state, DISEQC_MODE, &diseqc_mode); + if (ret < 0) return ret; + ret = zl10313_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40) | + tone_tab[tone]); + if (ret < 0) return ret; + return 0; +} + +static int zl10313_set_voltage(struct dvb_frontend *fe, + fe_sec_voltage_t voltage) +{ + struct zl10313_state *state = fe->demodulator_priv; + const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; + int ret; + u8 diseqc_mode; + + trace_printk("%s\n", __FUNCTION__); + params_printk("Set voltage %s (enum %d)\n", volt_name[voltage], + voltage); + if (voltage > SEC_VOLTAGE_OFF) return -EINVAL; + ret = zl10313_readreg(state, DISEQC_MODE, &diseqc_mode); + if (ret < 0) return ret; + ret = zl10313_writereg(state, DISEQC_MODE, (diseqc_mode & 0x07) | + volt_tab[voltage]); + if (ret < 0) return ret; + return 0; +} + +static void zl10313_release(struct dvb_frontend *fe) +{ + struct zl10313_state *state = fe->demodulator_priv; + + trace_printk("%s\n", __FUNCTION__); + kfree(state); +} + +static int zl10313_get_tune_settings(struct dvb_frontend *fe, + struct dvb_frontend_tune_settings *fesettings) +{ + fesettings->min_delay_ms = 100; + fesettings->step_size = 0; + fesettings->max_drift = 0; + return 0; +} + +static int zl10313_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct zl10313_state *state = fe->demodulator_priv; + u8 gpp_ctrl; + int ret; + + trace_printk("%s,\n", __FUNCTION__); + params_printk("Switching %d\n", enable); + ret = zl10313_readreg(state, GPP_CTRL, &gpp_ctrl); + if (ret < 0) return ret; + if (enable) { + return zl10313_writereg(state, GPP_CTRL, gpp_ctrl | 0x40); + } else { + return zl10313_writereg(state, GPP_CTRL, gpp_ctrl & ~0x40); + } +} + + +static struct dvb_frontend_ops zl10313_ops; + +struct dvb_frontend * zl10313_attach(const struct zl10313_config *config, + struct i2c_adapter *i2c) +{ + struct zl10313_state *state = NULL; + + trace_printk("%s\n", __FUNCTION__); + + state = kmalloc(sizeof(struct zl10313_state), GFP_KERNEL); + if (state == NULL) goto error; + + state->config = config; + state->i2c = i2c; + memcpy(&state->frontend.ops, &zl10313_ops, + sizeof(struct dvb_frontend_ops)); + + /* check if this is a valid demodulator */ + if (zl10313_readreg(state, ID, &state->id) < 0) goto error; + + switch (state->id) { + case ID_ZL10312: + strcpy(state->frontend.ops.info.name, "Zarlink ZL10312 DVB-S"); + break; + case ID_ZL10313: + strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S"); + break; + default: + eprintk("Chip ID does not match a known type\n"); + goto error; + } + state->frontend.demodulator_priv = state; + iprintk("Demodulator attached @ i2c address 0x%02x\n", + config->demod_address); + + zl10313_dump_registers(state); + return &state->frontend; +error: + kfree(state); + return NULL; +} + +static struct dvb_frontend_ops zl10313_ops = { + + .info = { + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 125, /* kHz for QPSK frontends */ + .frequency_tolerance = 29500, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | + FE_CAN_QPSK | FE_CAN_FEC_AUTO | FE_CAN_INVERSION_AUTO | + FE_CAN_RECOVER + }, + + .release = zl10313_release, + + .init = zl10313_init, + .sleep = zl10313_sleep, + + .set_frontend = zl10313_set_frontend, + .get_frontend = zl10313_get_frontend, + .get_tune_settings = zl10313_get_tune_settings, + + .read_status = zl10313_read_status, + .read_ber = zl10313_read_ber, + .read_signal_strength = zl10313_read_signal_strength, + .read_snr = zl10313_read_snr, + .read_ucblocks = zl10313_read_ucblocks, + + .diseqc_send_master_cmd = zl10313_send_master_cmd, + .diseqc_send_burst = zl10313_send_burst, + .set_voltage = zl10313_set_voltage, + .set_tone = zl10313_set_tone, + .i2c_gate_ctrl = zl10313_i2c_gate_ctrl, + +}; + +MODULE_DESCRIPTION("Zarlink ZL10313 DVB-S demodulator driver"); +MODULE_AUTHOR("Jan Daniël Louw "); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(zl10313_attach); diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10313.h v4l-dvb/linux/drivers/media/dvb/frontends/zl10313.h --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10313.h 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl10313.h 2007-12-31 15:04:12.000000000 +0100 @@ -0,0 +1,47 @@ +/* + Driver for Zarlink ZL10313 DVB-S demodulator + + Copyright (C) 2007 Jan Daniël Louw + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef ZL10313_H +#define ZL10313_H + + +struct zl10313_config +{ + /* demodulator's i2c address */ + u8 demod_address; +}; + + +#if defined(CONFIG_DVB_ZL10313) || (defined(CONFIG_DVB_ZL10313_MODULE) && \ +defined(MODULE)) +struct dvb_frontend * zl10313_attach(const struct zl10313_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend * zl10313_attach( + const struct zl10313_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); + return NULL; +} +#endif /* CONFIG_DVB_ZL10313 */ + +#endif /* ZL10313_H */ diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10313_priv.h v4l-dvb/linux/drivers/media/dvb/frontends/zl10313_priv.h --- v4l-dvb.20071229/linux/drivers/media/dvb/frontends/zl10313_priv.h 1970-01-01 01:00:00.000000000 +0100 +++ v4l-dvb/linux/drivers/media/dvb/frontends/zl10313_priv.h 2008-01-12 21:30:58.000000000 +0100 @@ -0,0 +1,275 @@ +/* + Driver for Zarlink ZL10313 DVB-S Frontend + + Copyright (C) 2007 Jan Daniël Louw + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef DVB_FRONTENDS_ZL10313_PRIV +#define DVB_FRONTENDS_ZL10313_PRIV + +/* Trace function calls */ +#define DEBUG_CALL_TRACE 0 +/* Trace read/write function calls - information overload */ +#define DEBUG_IO_TRACE 0 +/* Print register values at critical points */ +#define DEBUG_DUMP_REGISTERS 0 +/* Print important params passed to functions */ +#define DEBUG_PRINT_PARAMS 1 + +#if DEBUG_CALL_TRACE + #define trace_printk(args...) printk(KERN_DEBUG "demodulator: " \ + "zl10313: " args) +#else + #define trace_printk(args...) +#endif + +#if DEBUG_IO_TRACE + #define io_printk(args...) printk(KERN_DEBUG "demodulator: zl10313: " \ + args) +#else + #define io_printk(args...) +#endif + +#if DEBUG_PRINT_PARAMS + #define params_printk(args...) printk(KERN_DEBUG \ + "demodulator: zl10313: " args) +#else + #define params_printk(args...) +#endif + +#define eprintk(args...) printk(KERN_ERR "demodulator: zl10313: " args) +#define iprintk(args...) printk(KERN_INFO "demodulator: zl10313: " args) + +enum zl10313_model_id { + ID_VP310 = 1, + ID_MT312 = 3, + ID_ZL10312 = 4, + ID_ZL10313 = 5 +}; + +struct zl10313_state +{ + struct i2c_adapter *i2c; + const struct zl10313_config *config; + u8 id; + u32 prev_frequency; /* Store previously set frequency */ + struct dvb_frontend frontend; +}; + +enum zl10313_reg_addr { + QPSK_INT_H = 0, + QPSK_INT_M = 1, + QPSK_INT_L = 2, + FEC_INT = 3, + QPSK_STAT_H = 4, + QPSK_STAT_L = 5, + FEC_STATUS = 6, + LNB_FREQ_H = 7, + LNB_FREQ_L = 8, + M_SNR_H = 9, + M_SNR_L = 10, + VIT_ERRCNT_H = 11, + VIT_ERRCNT_M = 12, + VIT_ERRCNT_L = 13, + RS_BERCNT_H = 14, + RS_BERCNT_M = 15, + RS_BERCNT_L = 16, + RS_UBC_H = 17, + RS_UBC_L = 18, + SIG_LEVEL = 19, + GPP_CTRL = 20, + RESET = 21, + DISEQC_MODE = 22, + SYM_RATE_H = 23, + SYM_RATE_L = 24, + VIT_MODE = 25, + QPSK_CTRL = 26, + GO = 27, + IE_QPSK_H = 28, + IE_QPSK_M = 29, + IE_QPSK_L = 30, + IE_FEC = 31, + QPSK_STAT_EN = 32, + FEC_STAT_EN = 33, + SYS_CLK = 34, + DISEQC_RATIO = 35, + DISEQC_INSTR = 36, + FR_LIM = 37, + FR_OFF = 38, + AGC_CTRL = 39, + AGC_INIT = 40, + AGC_REF = 41, + AGC_MAX = 42, + AGC_MIN = 43, + AGC_LK_TH = 44, + TS_AGC_LK_TH = 45, + AGC_PWR_SET = 46, + QPSK_MISC = 47, + SNR_THS_LOW = 48, + SNR_THS_HIGH = 49, + TS_SW_RATE = 50, + TS_SW_LIM_L = 51, + TS_SW_LIM_H = 52, + CS_SW_RATE_1 = 53, + CS_SW_RATE_2 = 54, + CS_SW_RATE_3 = 55, + CS_SW_RATE_4 = 56, + CS_SW_LIM = 57, + TS_LPK = 58, + TS_LPK_M = 59, + TS_LPK_L = 60, + CS_KPROP_H = 61, + CS_KPROP_L = 62, + CS_KINT_H = 63, + CS_KINT_L = 64, + QPSK_SCALE = 65, + TLD_OUTCLK_TH = 66, + TLD_INCLK_TH = 67, + FLD_TH = 68, + PLD_OUTLK3 = 69, + PLD_OUTLK2 = 70, + PLD_OUTLK1 = 71, + PLD_OUTLK0 = 72, + PLD_INLK3 = 73, + PLD_INLK2 = 74, + PLD_INLK1 = 75, + PLD_INLK0 = 76, + PLD_ACC_TIME = 77, + SWEEP_PAR = 78, + STARTUP_TIME = 79, + LOSSLOCK_TH = 80, + FEC_LOCK_TM = 81, + LOSSLOCK_TM = 82, + VIT_ERRPER_H = 83, + VIT_ERRPER_M = 84, + VIT_ERRPER_L = 85, + VIT_SETUP = 86, + VIT_REF0 = 87, + VIT_REF1 = 88, + VIT_REF2 = 89, + VIT_REF3 = 90, + VIT_REF4 = 91, + VIT_REF5 = 92, + VIT_REF6 = 93, + VIT_MAXERR = 94, + BA_SETUPT = 95, + OP_CTRL = 96, + FEC_SETUP = 97, + PROG_SYNC = 98, + AFC_SEAR_TH = 99, + CSACC_DIF_TH = 100, + QPSK_LK_CT = 101, + QPSK_ST_CT = 102, + MON_CTRL = 103, + QPSK_RESET = 104, + QPSK_TST_CT = 105, + QPSK_TST_ST = 106, + TEST_R = 107, + AGC_H = 108, + AGC_M = 109, + AGC_L = 110, + FREQ_ERR1_H = 111, + FREQ_ERR1_M = 112, + FREQ_ERR1_L = 113, + FREQ_ERR2_H = 114, + FREQ_ERR2_L = 115, + SYM_RAT_OP_H = 116, + SYM_RAT_OP_L = 117, + DESEQC2_INT = 118, + DISEQC2_STAT = 119, + DISEQC2_FIFO = 120, + DISEQC2_CTRL1 = 121, + DISEQC2_CTRL2 = 122, + MONITOR_H = 123, + MONITOR_L = 124, + TEST_MODE = 125, + ID = 126, + CONFIG = 127 +}; + + +#if DEBUG_PRINT_PARAMS + static const char *inv_str[] = {"OFF", "ON", "AUTO"}; + static const char *fec_str[] = {"NONE", "1/2", "2/3", "3/4", "4/5", + "5/6", "6/7", "7/8", "8/9", "AUTO"}; + static const char *mini_cmd_name[] = {"SEC_MINI_A", "SEC_MINI_B"}; + static const char *tone_name[] = {"SEC_TONE_ON", "SEC_TONE_OFF"}; + static const char *volt_name[] = {"SEC_VOLTAGE_13", "SEC_VOLTAGE_18", + "SEC_VOLTAGE_OFF"}; +#endif + +#if DEBUG_DUMP_REGISTERS || DEBUG_IO_TRACE +static const char *zl10313_reg_names[] = { + "QPSK_INT_H", "QPSK_INT_M", "QPSK_INT_L", "FEC_INT", "QPSK_STAT_H", + "QPSK_STAT_L", "FEC_STATUS", "LNB_FREQ_H", "LNB_FREQ_L", "M_SNR_H", + "M_SNR_L", "VIT_ERRCNT_H", "VIT_ERRCNT_M", "VIT_ERRCNT_L", + "RS_BERCNT_H", "RS_BERCNT_M", "RS_BERCNT_L", "RS_UBC_H", "RS_UBC_L", + "SIG_LEVEL", "GPP_CTRL", "RESET", "DISEQC_MODE", "SYM_RATE_H", + "SYM_RATE_L", "VIT_MODE", "QPSK_CTRL", "GO", "IE_QPSK_H", "IE_QPSK_M", + "IE_QPSK_L", "IE_FEC", "QPSK_STAT_EN", "FEC_STAT_EN", "SYS_CLK", + "DISEQC_RATIO", "DISEQC_INSTR", "FR_LIM", "FR_OFF", "AGC_CTRL", + "AGC_INIT", "AGC_REF", "AGC_MAX", "AGC_MIN", "AGC_LK_TH", + "TS_AGC_LK_TH", "AGC_PWR_SET", "QPSK_MISC", "SNR_THS_LOW", + "SNR_THS_HIGH", "TS_SW_RATE", "TS_SW_LIM_L", "TS_SW_LIM_H", + "CS_SW_RATE_1", "CS_SW_RATE_2", "CS_SW_RATE_3", "CS_SW_RATE_4", + "CS_SW_LIM", "TS_LPK", "TS_LPK_M", "TS_LPK_L", "CS_KPROP_H", + "CS_KPROP_L", "CS_KINT_H", "CS_KINT_L", "QPSK_SCALE", "TLD_OUTCLK_TH", + "TLD_INCLK_TH", "FLD_TH", "PLD_OUTLK3", "PLD_OUTLK2", "PLD_OUTLK1", + "PLD_OUTLK0", "PLD_INLK3", "PLD_INLK2", "PLD_INLK1", "PLD_INLK0", + "PLD_ACC_TIME", "SWEEP_PAR", "STARTUP_TIME", "LOSSLOCK_TH", + "FEC_LOCK_TM", "LOSSLOCK_TM", "VIT_ERRPER_H", "VIT_ERRPER_M", + "VIT_ERRPER_L", "VIT_SETUP", "VIT_REF0", "VIT_REF1", "VIT_REF2", + "VIT_REF3", "VIT_REF4", "VIT_REF5", "VIT_REF6", "VIT_MAXERR", + "BA_SETUPT", "OP_CTRL", "FEC_SETUP", "PROG_SYNC", "AFC_SEAR_TH", + "CSACC_DIF_TH", "QPSK_LK_CT", "QPSK_ST_CT", "MON_CTRL", "QPSK_RESET", + "QPSK_TST_CT", "QPSK_TST_ST", "TEST_R", "AGC_H", "AGC_M", "AGC_L", + "FREQ_ERR1_H", "FREQ_ERR1_M", "FREQ_ERR1_L", "FREQ_ERR2_H", + "FREQ_ERR2_L", "SYM_RAT_OP_H", "SYM_RAT_OP_L", "DESEQC2_INT", + "DISEQC2_STAT", "DISEQC2_FIFO", "DISEQC2_CTRL1", "DISEQC2_CTRL2", + "MONITOR_H", "MONITOR_L", "TEST_MODE", "ID", "CONFIG", "" +}; +#endif + +#if DEBUG_DUMP_REGISTERS +static int zl10313_read(const struct zl10313_state *state, + const enum zl10313_reg_addr reg, u8 *buf, + const size_t count); + +static void zl10313_dump_registers(const struct zl10313_state *state) +{ + int ret; + u8 buf[128]; + u8 reg ; + + trace_printk("%s\n", __FUNCTION__); + ret = zl10313_read(state, QPSK_INT_H, buf, sizeof(buf)); + if (ret < 0) return; + for (reg = QPSK_INT_H; reg <= CONFIG; reg += 4) { + printk(KERN_DEBUG "%03x: [%02x %13s] [%02x %13s] [%02x %13s] " + "[%02x %13s]\n", reg, buf[reg], zl10313_reg_names[reg], + buf[reg+1], zl10313_reg_names[reg+1], buf[reg+2], + zl10313_reg_names[reg+2], buf[reg+3], + zl10313_reg_names[reg+3]); + } +} +#else +static inline void zl10313_dump_registers(const struct zl10313_state *state) {} +#endif /* DEBUG_DUMP_REGISTERS */ + +#endif /* DVB_FRONTENDS_ZL10313_PRIV */ diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/video/saa7134/Kconfig v4l-dvb/linux/drivers/media/video/saa7134/Kconfig --- v4l-dvb.20071229/linux/drivers/media/video/saa7134/Kconfig 2007-12-29 22:34:27.000000000 +0100 +++ v4l-dvb/linux/drivers/media/video/saa7134/Kconfig 2007-12-31 15:05:52.000000000 +0100 @@ -37,6 +37,9 @@ select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_TDA827X if !DVB_FE_CUSTOMISE select DVB_ISL6421 if !DVB_FE_CUSTOMISE + select DVB_ZL10313 if !DVB_FE_CUSTOMISE + select DVB_ZL10039 if !DVB_FE_CUSTOMISE + select DVB_ZL1003X if !DVB_FE_CUSTOMISE ---help--- This adds support for DVB cards based on the Philips saa7134 chip. diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134-cards.c v4l-dvb/linux/drivers/media/video/saa7134/saa7134-cards.c --- v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134-cards.c 2007-12-29 22:34:27.000000000 +0100 +++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-cards.c 2007-12-31 15:05:36.000000000 +0100 @@ -3269,7 +3269,6 @@ .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, - .tuner_config = 1, .mpeg = SAA7134_MPEG_DVB, .inputs = {{ .name = name_tv, @@ -3601,6 +3600,59 @@ .tv = 1, }}, }, + [SAA7134_BOARD_AVERMEDIA_A700] = { + .name = "Avermedia AVerTV DVB-S Pro (A700)", + //.audio_clock = 0x90909090, + .audio_clock = 0x00187de7, + .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + /* GPIO @ winxp: + * + * SAA7134_GPIO_GPMODE: 80040100 (10000000 00000100 00000001 00000000) + * SAA7134_GPIO_GPSTATUS: 0454fb00 (00000100 01010100 11111011 00000000) + * + * Linux: gpio is 200fe00 + */ + .inputs = { + { + .name = name_tv, + .vmux = 4, + .amux = 1, + .tv = 1, + }, + { + .name = name_comp1, + .vmux = 1, + .amux = 2, + },{ + .name = name_svideo, + .vmux = 6, + .amux = 2, + }}, + }, + [SAA7134_BOARD_VIDEOMATE_S350] = { + /* Jan Daniël Louw has_remote = SAA7134_REMOTE_GPIO; saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007); saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd); break; + case SAA7134_BOARD_VIDEOMATE_S350: + saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x00008000, 0x00008000); + saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x00008000, 0x00008000); + dev->has_remote = SAA7134_REMOTE_GPIO; + break; } return 0; } diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134-dvb.c v4l-dvb/linux/drivers/media/video/saa7134/saa7134-dvb.c --- v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134-dvb.c 2007-12-29 22:34:27.000000000 +0100 +++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-dvb.c 2007-12-31 15:05:36.000000000 +0100 @@ -38,6 +38,9 @@ #include "mt352_priv.h" /* FIXME */ #include "tda1004x.h" #include "nxt200x.h" +#include "zl10313.h" +#include "zl10039.h" +#include "zl1003x.h" #include "tda10086.h" #include "tda826x.h" @@ -662,7 +665,6 @@ .if_freq = TDA10046_FREQ_045, .i2c_gate = 0x4b, .tuner_address = 0x61, - .tuner_config = 1, .request_firmware = philips_tda1004x_request_firmware }; @@ -841,6 +843,27 @@ }; /* ================================================================== + * ZL10313 based DVB-S cards + */ +static struct zl10313_config zl10313_compro_s350_config = { + .demod_address = 0x0E, +}; + +static struct zl10313_config zl10313_avertv_a700_config = { + .demod_address = 0x0e, /* Avermedia DVB-S Pro A700-B */ +}; + +static struct zl10039_config zl10039_compro_s350_config = { + .tuner_address = 0x60, +}; + +static struct zl1003x_config zl1003x_avertv_a700_config = { + .tuner_address = 0x60, + .tuner_type = ZL1003X_TYPE_ZL10036, + .has_loopthrough = 0, +}; + +/* ================================================================== * Core code */ @@ -1044,6 +1067,24 @@ case SAA7134_BOARD_AVERMEDIA_SUPER_007: configure_tda827x_fe(dev, &avermedia_super_007_config); break; + case SAA7134_BOARD_VIDEOMATE_S350: + dev->dvb.frontend = dvb_attach(zl10313_attach, + &zl10313_compro_s350_config, &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend = dvb_attach(zl10039_attach, + dev->dvb.frontend, &zl10039_compro_s350_config, + &dev->i2c_adap); + } + break; + case SAA7134_BOARD_AVERMEDIA_A700: + dev->dvb.frontend = dvb_attach(zl10313_attach, + &zl10313_avertv_a700_config, &dev->i2c_adap); + if (dev->dvb.frontend) { + dev->dvb.frontend = dvb_attach(zl1003x_attach, + dev->dvb.frontend, &zl1003x_avertv_a700_config, + &dev->i2c_adap); + } + break; default: wprintk("Huh? unknown DVB card?\n"); break; diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134.h v4l-dvb/linux/drivers/media/video/saa7134/saa7134.h --- v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134.h 2007-12-29 22:34:27.000000000 +0100 +++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134.h 2007-12-31 15:05:29.000000000 +0100 @@ -247,6 +247,8 @@ #define SAA7134_BOARD_SABRENT_TV_PCB05 115 #define SAA7134_BOARD_10MOONSTVMASTER3 116 #define SAA7134_BOARD_AVERMEDIA_SUPER_007 117 +#define SAA7134_BOARD_VIDEOMATE_S350 118 +#define SAA7134_BOARD_AVERMEDIA_A700 119 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134-input.c v4l-dvb/linux/drivers/media/video/saa7134/saa7134-input.c --- v4l-dvb.20071229/linux/drivers/media/video/saa7134/saa7134-input.c 2007-12-29 22:34:27.000000000 +0100 +++ v4l-dvb/linux/drivers/media/video/saa7134/saa7134-input.c 2007-12-31 15:05:36.000000000 +0100 @@ -260,7 +260,6 @@ case SAA7134_BOARD_AVERMEDIA_STUDIO_307: case SAA7134_BOARD_AVERMEDIA_STUDIO_507: case SAA7134_BOARD_AVERMEDIA_GO_007_FM: - case SAA7134_BOARD_AVERMEDIA_M102: ir_codes = ir_codes_avermedia; mask_keycode = 0x0007C8; mask_keydown = 0x000010; @@ -352,6 +351,11 @@ mask_keyup = 0x8000000; polling = 50; //ms break; + case SAA7134_BOARD_VIDEOMATE_S350: + ir_codes = ir_codes_videomate_s350; + mask_keycode = 0x003F00; + mask_keydown = 0x040000; + break; } if (NULL == ir_codes) { printk("%s: Oops: IR config error [card=%d]\n", diff --exclude-from=MakeDiff-Excludes -urN v4l-dvb.20071229/linux/include/media/ir-common.h v4l-dvb/linux/include/media/ir-common.h --- v4l-dvb.20071229/linux/include/media/ir-common.h 2007-12-29 22:34:27.000000000 +0100 +++ v4l-dvb/linux/include/media/ir-common.h 2007-12-31 15:06:31.000000000 +0100 @@ -140,6 +140,7 @@ extern IR_KEYTAB_TYPE ir_codes_encore_enltv[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_tt_1500[IR_KEYTAB_SIZE]; extern IR_KEYTAB_TYPE ir_codes_fusionhdtv_mce[IR_KEYTAB_SIZE]; +extern IR_KEYTAB_TYPE ir_codes_videomate_s350[IR_KEYTAB_SIZE]; #endif