diff options
34 files changed, 1501 insertions, 274 deletions
@@ -1,13 +1,6 @@ BUILD_DIR := $(shell pwd)/v4l TMP ?= /tmp REPO_PULL := http://linuxtv.org/hg/v4l-dvb -ifeq ($(REPO_PUSH),) - ifneq ($(CHANGE_LOG_LOGIN),) - REPO_PUSH := ssh://$(CHANGE_LOG_LOGIN)@linuxtv.org/hg/v4l-dvb - else - REPO_PUSH := ssh://linuxtv.org/hg/v4l-dvb - endif -endif ifeq ($(EDITOR),) ifeq ($(VISUAL),) @@ -40,8 +33,8 @@ pull update v4l-update:: -hg pull -u $(REPO_PULL) push:: - @echo "Pushing changes to master repository $(REPO_PUSH)" - -hg push $(REPO_PUSH) + @echo "Pushing changes to master repository" + -hg push whitespace: @echo "Cleaning bad whitespaces" diff --git a/linux/Documentation/video4linux/CARDLIST.saa7134 b/linux/Documentation/video4linux/CARDLIST.saa7134 index dba69335c..ac1357d47 100644 --- a/linux/Documentation/video4linux/CARDLIST.saa7134 +++ b/linux/Documentation/video4linux/CARDLIST.saa7134 @@ -95,3 +95,4 @@ 94 -> LifeView FlyDVB-T Hybrid Cardbus [5168:3306,5168:3502] 95 -> LifeView FlyVIDEO3000 (NTSC) [5169:0138] 96 -> Medion Md8800 Quadro [16be:0007,16be:0008] + 97 -> LifeView FlyDVB-S /Acorp TV134DS [5168:0300,4e42:0300] diff --git a/linux/drivers/media/dvb/dvb-core/Makefile b/linux/drivers/media/dvb/dvb-core/Makefile index 11054657f..0b5182835 100644 --- a/linux/drivers/media/dvb/dvb-core/Makefile +++ b/linux/drivers/media/dvb/dvb-core/Makefile @@ -2,8 +2,8 @@ # Makefile for the kernel DVB device drivers. # -dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_ca_en50221.o dvb_frontend.o \ - dvb_net.o dvb_ringbuffer.o dvb_math.o +dvb-core-objs := dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ + dvb_ca_en50221.o dvb_frontend.o \ + dvb_net.o dvb_ringbuffer.o dvb_math.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 191fa4de7..8b64be1a3 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -17,49 +17,56 @@ comment "DVB-S (satellite) frontends" config DVB_STV0299 tristate "ST STV0299 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_CX24110 tristate "Conexant CX24110 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_CX24123 tristate "Conexant CX24123 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_TDA8083 tristate "Philips TDA8083 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_MT312 tristate "Zarlink VP310/MT312 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_VES1X93 tristate "VLSI VES1893 or VES1993 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. config DVB_S5H1420 tristate "Samsung S5H1420 based" - depends on DVB_CORE + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S tuner module. Say Y when you want to support this frontend. + +config DVB_TDA10086 + tristate "Philips TDA10086 based" + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-S tuner module. Say Y when you want to support this frontend. @@ -69,7 +76,7 @@ comment "DVB-T (terrestrial) frontends" config DVB_SP8870 tristate "Spase sp8870 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -82,7 +89,7 @@ config DVB_SP8870 config DVB_SP887X tristate "Spase sp887x based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -95,28 +102,28 @@ config DVB_SP887X config DVB_CX22700 tristate "Conexant CX22700 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_CX22702 tristate "Conexant cx22702 demodulator (OFDM)" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_L64781 tristate "LSI L64781" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_TDA1004X tristate "Philips TDA10045H/TDA10046H based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -130,28 +137,28 @@ config DVB_TDA1004X config DVB_NXT6000 tristate "NxtWave Communications NXT6000 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_MT352 tristate "Zarlink MT352 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_ZL10353 tristate "Zarlink ZL10353 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Say Y when you want to support this frontend. config DVB_DIB3000MB tristate "DiBcom 3000M-B" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Designed for mobile usage. Say Y when you want @@ -159,7 +166,7 @@ config DVB_DIB3000MB config DVB_DIB3000MC tristate "DiBcom 3000P/M-C" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-T tuner module. Designed for mobile usage. Say Y when you want @@ -170,21 +177,21 @@ comment "DVB-C (cable) frontends" config DVB_VES1820 tristate "VLSI VES1820 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-C tuner module. Say Y when you want to support this frontend. config DVB_TDA10021 tristate "Philips TDA10021 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-C tuner module. Say Y when you want to support this frontend. config DVB_STV0297 tristate "ST STV0297 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help A DVB-C tuner module. Say Y when you want to support this frontend. @@ -194,7 +201,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends" config DVB_NXT200X tristate "NxtWave Communications NXT2002/NXT2004 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -209,7 +216,7 @@ config DVB_NXT200X config DVB_OR51211 tristate "Oren OR51211 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -222,7 +229,7 @@ config DVB_OR51211 config DVB_OR51132 tristate "Oren OR51132 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -238,7 +245,7 @@ config DVB_OR51132 config DVB_BCM3510 tristate "Broadcom BCM3510" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE select FW_LOADER help @@ -247,32 +254,42 @@ config DVB_BCM3510 config DVB_LGDT330X tristate "LG Electronics LGDT3302/LGDT3303 based" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +comment "Tuners/PLL support" + depends on DVB_CORE + +config DVB_TDA826X + tristate "Philips TDA826X silicon tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + A DVB-S silicon tuner module. Say Y when you want to support this tuner. + +config DVB_TUNER_MT2060 + tristate "Microtune MT2060 silicon IF tuner" + help + A driver for the silicon IF tuner MT2060 from Microtune. + comment "Miscellaneous devices" depends on DVB_CORE config DVB_LNBP21 tristate "LNBP21 SEC controller" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help An SEC control chip. config DVB_ISL6421 tristate "ISL6421 SEC controller" - depends on DVB_CORE + depends on DVB_CORE && I2C default m if DVB_FE_CUSTOMISE help An SEC control chip. -config DVB_TUNER_MT2060 - tristate "Microtune MT2060 silicon IF tuner" - help - A driver for the silicon IF tuner MT2060 from Microtune. - endmenu diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index a7fbd0fab..4d0c05115 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -33,4 +33,6 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_ISL6421) += isl6421.o +obj-$(CONFIG_DVB_TDA10086) += tda10086.o +obj-$(CONFIG_DVB_TDA826X) += tda826x.o obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c new file mode 100644 index 000000000..7456b0b99 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/tda10086.c @@ -0,0 +1,740 @@ + /* + Driver for Philips tda10086 DVBS Demodulator + + (c) 2006 Andrew de Quincey + + 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 <linux/init.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/device.h> +#include <linux/jiffies.h> +#include <linux/string.h> +#include <linux/slab.h> + +#include "dvb_frontend.h" +#include "tda10086.h" + +#define SACLK 96000000 + +struct tda10086_state { + struct i2c_adapter* i2c; + const struct tda10086_config* config; + struct dvb_frontend frontend; + + /* private demod data */ + u32 frequency; + u32 symbol_rate; +}; + +static int debug = 0; +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG "tda10086: " args); \ + } while (0) + +static int tda10086_write_byte(struct tda10086_state *state, int reg, int data) +{ + int ret; + u8 b0[] = { reg, data }; + struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 }; + + msg.addr = state->config->demod_address; + ret = i2c_transfer(state->i2c, &msg, 1); + + if (ret != 1) + dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n", + __FUNCTION__, reg, data, ret); + + return (ret != 1) ? ret : 0; +} + +static int tda10086_read_byte(struct tda10086_state *state, int reg) +{ + int ret; + u8 b0[] = { reg }; + u8 b1[] = { 0 }; + struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, + { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; + + msg[0].addr = state->config->demod_address; + msg[1].addr = state->config->demod_address; + ret = i2c_transfer(state->i2c, msg, 2); + + if (ret != 2) { + dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg, + ret); + return ret; + } + + return b1[0]; +} + +static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data) +{ + int val; + + // read a byte and check + val = tda10086_read_byte(state, reg); + if (val < 0) + return val; + + // mask if off + val = val & ~mask; + val |= data & 0xff; + + // write it out again + return tda10086_write_byte(state, reg, val); +} + +static int tda10086_init(struct dvb_frontend* fe) +{ + struct tda10086_state* state = fe->demodulator_priv; + + dprintk ("%s\n", __FUNCTION__); + + // reset + tda10086_write_byte(state, 0x00, 0x00); + msleep(10); + + // misc setup + tda10086_write_byte(state, 0x01, 0x94); + tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP + tda10086_write_byte(state, 0x03, 0x64); + tda10086_write_byte(state, 0x04, 0x43); + tda10086_write_byte(state, 0x0c, 0x0c); + tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold + tda10086_write_byte(state, 0x20, 0x89); // misc + tda10086_write_byte(state, 0x30, 0x04); // acquisition period length + tda10086_write_byte(state, 0x32, 0x00); // irq off + tda10086_write_byte(state, 0x31, 0x56); // setup AFC + + // setup PLL (assumes 16Mhz XIN) + tda10086_write_byte(state, 0x55, 0x2c); // misc PLL setup + tda10086_write_byte(state, 0x3a, 0x0b); // M=12 + tda10086_write_byte(state, 0x3b, 0x01); // P=2 + tda10086_write_mask(state, 0x55, 0x20, 0x00); // powerup PLL + + // setup TS interface + tda10086_write_byte(state, 0x11, 0x81); + tda10086_write_byte(state, 0x12, 0x81); + tda10086_write_byte(state, 0x19, 0x40); // parallel mode A + MSBFIRST + tda10086_write_byte(state, 0x56, 0x80); // powerdown WPLL - unused in the mode we use + tda10086_write_byte(state, 0x57, 0x08); // bypass WPLL - unused in the mode we use + tda10086_write_byte(state, 0x10, 0x2a); + + // setup ADC + tda10086_write_byte(state, 0x58, 0x61); // ADC setup + tda10086_write_mask(state, 0x58, 0x01, 0x00); // powerup ADC + + // setup AGC + tda10086_write_byte(state, 0x05, 0x0B); + tda10086_write_byte(state, 0x37, 0x63); + tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it + tda10086_write_byte(state, 0x40, 0x64); + tda10086_write_byte(state, 0x41, 0x4f); + tda10086_write_byte(state, 0x42, 0x43); + + // setup viterbi + tda10086_write_byte(state, 0x1a, 0x11); // VBER 10^6, DVB, QPSK + + // setup carrier recovery + tda10086_write_byte(state, 0x3d, 0x80); + + // setup SEC + tda10086_write_byte(state, 0x36, 0x00); // all SEC off + tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency + tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // } + + return 0; +} + +static void tda10086_diseqc_wait(struct tda10086_state *state) +{ + unsigned long timeout = jiffies + msecs_to_jiffies(200); + while (!(tda10086_read_byte(state, 0x50) & 0x01)) { + if(time_after(jiffies, timeout)) { + printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__); + break; + } + msleep(10); + } +} + +static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +{ + struct tda10086_state* state = fe->demodulator_priv; + + dprintk ("%s\n", __FUNCTION__); + + switch(tone) { + case SEC_TONE_OFF: + tda10086_write_byte(state, 0x36, 0x00); + break; + + case SEC_TONE_ON: + tda10086_write_byte(state, 0x36, 0x01); + break; + } + + return 0; +} + +static int tda10086_send_master_cmd (struct dvb_frontend* fe, + struct dvb_diseqc_master_cmd* cmd) +{ + struct tda10086_state* state = fe->demodulator_priv; + int i; + u8 oldval; + + dprintk ("%s\n", __FUNCTION__); + + if (cmd->msg_len > 6) + return -EINVAL; + oldval = tda10086_read_byte(state, 0x36); + + for(i=0; i< cmd->msg_len; i++) { + tda10086_write_byte(state, 0x48+i, cmd->msg[i]); + } + tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len + 1) << 4)); + + tda10086_diseqc_wait(state); + + tda10086_write_byte(state, 0x36, oldval); + + return 0; +} + +static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) +{ + struct tda10086_state* state = fe->demodulator_priv; + u8 oldval = tda10086_read_byte(state, 0x36); + + dprintk ("%s\n", __FUNCTION__); + + switch(minicmd) { + case SEC_MINI_A: + tda10086_write_byte(state, 0x36, 0x04); + break; + + case SEC_MINI_B: + tda10086_write_byte(state, 0x36, 0x06); + break; + } + + tda10086_diseqc_wait(state); + + tda10086_write_byte(state, 0x36, oldval); + + return 0; +} + +static int tda10086_set_inversion(struct tda10086_state *state, + struct dvb_frontend_parameters *fe_params) +{ + u8 invval = 0x80; + + dprintk ("%s %i %i\n", __FUNCTION__, fe_params->inversion, state->config->invert); + + switch(fe_params->inversion) { + case INVERSION_OFF: + if (state->config->invert) + invval = 0x40; + break; + case INVERSION_ON: + if (!state->config->invert) + invval = 0x40; + break; + case INVERSION_AUTO: + invval = 0x00; + break; + } + tda10086_write_mask(state, 0x0c, 0xc0, invval); + + return 0; +} + +static int tda10086_set_symbol_rate(struct tda10086_state *state, + struct dvb_frontend_parameters *fe_params) +{ + u8 dfn = 0; + u8 afs = 0; + u8 byp = 0; + u8 reg37 = 0x43; + u8 reg42 = 0x43; + u64 big; + u32 tmp; + u32 bdr; + u32 bdri; + u32 symbol_rate = fe_params->u.qpsk.symbol_rate; + + dprintk ("%s %i\n", __FUNCTION__, symbol_rate); + + // setup the decimation and anti-aliasing filters.. + if (symbol_rate < (u32) (SACLK * 0.0137)) { + dfn=4; + afs=1; + } else if (symbol_rate < (u32) (SACLK * 0.0208)) { + dfn=4; + afs=0; + } else if (symbol_rate < (u32) (SACLK * 0.0270)) { + dfn=3; + afs=1; + } else if (symbol_rate < (u32) (SACLK * 0.0416)) { + dfn=3; + afs=0; + } else if (symbol_rate < (u32) (SACLK * 0.0550)) { + dfn=2; + afs=1; + } else if (symbol_rate < (u32) (SACLK * 0.0833)) { + dfn=2; + afs=0; + } else if (symbol_rate < (u32) (SACLK * 0.1100)) { + dfn=1; + afs=1; + } else if (symbol_rate < (u32) (SACLK * 0.1666)) { + dfn=1; + afs=0; + } else if (symbol_rate < (u32) (SACLK * 0.2200)) { + dfn=0; + afs=1; + } else if (symbol_rate < (u32) (SACLK * 0.3333)) { + dfn=0; + afs=0; + } else { + reg37 = 0x63; + reg42 = 0x4f; + byp=1; + } + + // calculate BDR + big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn); + big += ((SACLK/1000ULL)-1ULL); + do_div(big, (SACLK/1000ULL)); + bdr = big & 0xfffff; + + // calculate BDRI + tmp = (1<<dfn)*(symbol_rate/1000); + bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp; + + tda10086_write_byte(state, 0x21, (afs << 7) | dfn); + tda10086_write_mask(state, 0x20, 0x08, byp << 3); + tda10086_write_byte(state, 0x06, bdr); + tda10086_write_byte(state, 0x07, bdr >> 8); + tda10086_write_byte(state, 0x08, bdr >> 16); + tda10086_write_byte(state, 0x09, bdri); + tda10086_write_byte(state, 0x37, reg37); + tda10086_write_byte(state, 0x42, reg42); + + return 0; +} + +static int tda10086_set_fec(struct tda10086_state *state, + struct dvb_frontend_parameters *fe_params) +{ + u8 fecval; + + dprintk ("%s %i\n", __FUNCTION__, fe_params->u.qpsk.fec_inner); + + switch(fe_params->u.qpsk.fec_inner) { + case FEC_1_2: + fecval = 0x00; + break; + case FEC_2_3: + fecval = 0x01; + break; + case FEC_3_4: + fecval = 0x02; + break; + case FEC_4_5: + fecval = 0x03; + break; + case FEC_5_6: + fecval = 0x04; + break; + case FEC_6_7: + fecval = 0x05; + break; + case FEC_7_8: + fecval = 0x06; + break; + case FEC_8_9: + fecval = 0x07; + break; + case FEC_AUTO: + fecval = 0x08; + break; + default: + return -1; + } + tda10086_write_byte(state, 0x0d, fecval); + + return 0; +} + +static int tda10086_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fe_params) +{ + struct tda10086_state *state = fe->demodulator_priv; + int ret; + u32 freq = 0; + int freqoff; + + dprintk ("%s\n", __FUNCTION__); + + // set params + if (fe->ops.tuner_ops.set_params) { + fe->ops.tuner_ops.set_params(fe, fe_params); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (fe->ops.tuner_ops.get_frequency) + fe->ops.tuner_ops.get_frequency(fe, &freq); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + } + + // calcluate the frequency offset (in *Hz* not kHz) + freqoff = fe_params->frequency - freq; + freqoff = ((1<<16) * freqoff) / (SACLK/1000); + tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f)); + tda10086_write_byte(state, 0x3e, freqoff); + + if ((ret = tda10086_set_inversion(state, fe_params)) < 0) + return ret; + if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0) + return ret; + if ((ret = tda10086_set_fec(state, fe_params)) < 0) + return ret; + + // soft reset + disable TS output until lock + tda10086_write_mask(state, 0x10, 0x40, 0x40); + tda10086_write_mask(state, 0x00, 0x01, 0x00); + + state->symbol_rate = fe_params->u.qpsk.symbol_rate; + state->frequency = fe_params->frequency; + return 0; +} + +static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params) +{ + struct tda10086_state* state = fe->demodulator_priv; + u8 val; + int tmp; + u64 tmp64; + + dprintk ("%s\n", __FUNCTION__); + + // calculate the updated frequency (note: we convert from Hz->kHz) + tmp64 = tda10086_read_byte(state, 0x52); + tmp64 |= (tda10086_read_byte(state, 0x51) << 8); + if (tmp64 & 0x8000) + tmp64 |= 0xffffffffffff0000ULL; + tmp64 = (tmp64 * (SACLK/1000ULL)); + do_div(tmp64, (1ULL<<15) * (1ULL<<1)); + fe_params->frequency = (int) state->frequency + (int) tmp64; + + // the inversion + val = tda10086_read_byte(state, 0x0c); + if (val & 0x80) { + switch(val & 0x40) { + case 0x00: + fe_params->inversion = INVERSION_OFF; + if (state->config->invert) + fe_params->inversion = INVERSION_ON; + break; + default: + fe_params->inversion = INVERSION_ON; + if (state->config->invert) + fe_params->inversion = INVERSION_OFF; + break; + } + } else { + tda10086_read_byte(state, 0x0f); + switch(val & 0x02) { + case 0x00: + fe_params->inversion = INVERSION_OFF; + if (state->config->invert) + fe_params->inversion = INVERSION_ON; + break; + default: + fe_params->inversion = INVERSION_ON; + if (state->config->invert) + fe_params->inversion = INVERSION_OFF; + break; + } + } + + // calculate the updated symbol rate + tmp = tda10086_read_byte(state, 0x1d); + if (tmp & 0x80) + tmp |= 0xffffff00; + tmp = (tmp * 480 * (1<<1)) / 128; + tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000); + fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp; + + // the FEC + val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4; + switch(val) { + case 0x00: + fe_params->u.qpsk.fec_inner = FEC_1_2; + break; + case 0x01: + fe_params->u.qpsk.fec_inner = FEC_2_3; + break; + case 0x02: + fe_params->u.qpsk.fec_inner = FEC_3_4; + break; + case 0x03: + fe_params->u.qpsk.fec_inner = FEC_4_5; + break; + case 0x04: + fe_params->u.qpsk.fec_inner = FEC_5_6; + break; + case 0x05: + fe_params->u.qpsk.fec_inner = FEC_6_7; + break; + case 0x06: + fe_params->u.qpsk.fec_inner = FEC_7_8; + break; + case 0x07: + fe_params->u.qpsk.fec_inner = FEC_8_9; + break; + } + + return 0; +} + +static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status) +{ + struct tda10086_state* state = fe->demodulator_priv; + u8 val; + + dprintk ("%s\n", __FUNCTION__); + + val = tda10086_read_byte(state, 0x0e); + *fe_status = 0; + if (val & 0x01) + *fe_status |= FE_HAS_SIGNAL; + if (val & 0x02) + *fe_status |= FE_HAS_CARRIER; + if (val & 0x04) + *fe_status |= FE_HAS_VITERBI; + if (val & 0x08) + *fe_status |= FE_HAS_SYNC; + if (val & 0x10) + *fe_status |= FE_HAS_LOCK; + + return 0; +} + +static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal) +{ + struct tda10086_state* state = fe->demodulator_priv; + u8 _str; + + dprintk ("%s\n", __FUNCTION__); + + _str = tda10086_read_byte(state, 0x43); + *signal = (_str << 8) | _str; + + return 0; +} + +static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr) +{ + struct tda10086_state* state = fe->demodulator_priv; + u8 _snr; + + dprintk ("%s\n", __FUNCTION__); + + _snr = tda10086_read_byte(state, 0x1c); + *snr = (_snr << 8) | _snr; + + return 0; +} + +static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) +{ + struct tda10086_state* state = fe->demodulator_priv; + + dprintk ("%s\n", __FUNCTION__); + + // read it + *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f; + + // reset counter + tda10086_write_byte(state, 0x18, 0x00); + tda10086_write_byte(state, 0x18, 0x80); + + return 0; +} + +static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber) +{ + struct tda10086_state* state = fe->demodulator_priv; + + dprintk ("%s\n", __FUNCTION__); + + // read it + *ber = 0; + *ber |= tda10086_read_byte(state, 0x15); + *ber |= tda10086_read_byte(state, 0x16) << 8; + *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16; + + return 0; +} + +static int tda10086_sleep(struct dvb_frontend* fe) +{ + struct tda10086_state* state = fe->demodulator_priv; + + dprintk ("%s\n", __FUNCTION__); + + tda10086_write_mask(state, 0x00, 0x08, 0x08); + + return 0; +} + +static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable) +{ + struct tda10086_state* state = fe->demodulator_priv; + + dprintk ("%s\n", __FUNCTION__); + + if (enable) { + tda10086_write_mask(state, 0x00, 0x10, 0x10); + } else { + tda10086_write_mask(state, 0x00, 0x10, 0x00); + } + + return 0; +} + +static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) +{ + if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) { + fesettings->min_delay_ms = 50; + fesettings->step_size = 2000; + fesettings->max_drift = 8000; + } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) { + fesettings->min_delay_ms = 100; + fesettings->step_size = 1500; + fesettings->max_drift = 9000; + } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) { + fesettings->min_delay_ms = 100; + fesettings->step_size = 1000; + fesettings->max_drift = 8000; + } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) { + fesettings->min_delay_ms = 100; + fesettings->step_size = 500; + fesettings->max_drift = 7000; + } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) { + fesettings->min_delay_ms = 200; + fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); + fesettings->max_drift = 14 * fesettings->step_size; + } else { + fesettings->min_delay_ms = 200; + fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000); + fesettings->max_drift = 18 * fesettings->step_size; + } + + return 0; +} + +static void tda10086_release(struct dvb_frontend* fe) +{ + struct tda10086_state *state = fe->demodulator_priv; + tda10086_sleep(fe); + kfree(state); +} + +static struct dvb_frontend_ops tda10086_ops = { + + .info = { + .name = "Philips TDA10086 DVB-S", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 125, /* kHz for QPSK frontends */ + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .caps = FE_CAN_INVERSION_AUTO | + 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_FEC_AUTO | + FE_CAN_QPSK + }, + + .release = tda10086_release, + + .init = tda10086_init, + .sleep = tda10086_sleep, + .i2c_gate_ctrl = tda10086_i2c_gate_ctrl, + + .set_frontend = tda10086_set_frontend, + .get_frontend = tda10086_get_frontend, + .get_tune_settings = tda10086_get_tune_settings, + + .read_status = tda10086_read_status, + .read_ber = tda10086_read_ber, + .read_signal_strength = tda10086_read_signal_strength, + .read_snr = tda10086_read_snr, + .read_ucblocks = tda10086_read_ucblocks, + + .diseqc_send_master_cmd = tda10086_send_master_cmd, + .diseqc_send_burst = tda10086_send_burst, + .set_tone = tda10086_set_tone, +}; + +struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, + struct i2c_adapter* i2c) +{ + struct tda10086_state *state; + + dprintk ("%s\n", __FUNCTION__); + + /* allocate memory for the internal state */ + state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL); + if (!state) + return NULL; + + /* setup the state */ + state->config = config; + state->i2c = i2c; + + /* check if the demod is there */ + if (tda10086_read_byte(state, 0x1e) != 0xe1) { + kfree(state); + return NULL; + } + + /* create dvb_frontend */ + memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; +} + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator"); +MODULE_AUTHOR("Andrew de Quincey"); +MODULE_LICENSE("GPL"); + +EXPORT_SYMBOL(tda10086_attach); diff --git a/linux/drivers/media/dvb/frontends/tda10086.h b/linux/drivers/media/dvb/frontends/tda10086.h new file mode 100644 index 000000000..e8061db11 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/tda10086.h @@ -0,0 +1,41 @@ + /* + Driver for Philips tda10086 DVBS Frontend + + (c) 2006 Andrew de Quincey + + 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 TDA10086_H +#define TDA10086_H + +#include <linux/dvb/frontend.h> +#include <linux/firmware.h> + +struct tda10086_config +{ + /* the demodulator's i2c address */ + u8 demod_address; + + /* does the "inversion" need inverted? */ + u8 invert; +}; + +extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config, + struct i2c_adapter* i2c); + +#endif // TDA10086_H diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c new file mode 100644 index 000000000..7c19b88e9 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/tda826x.c @@ -0,0 +1,173 @@ + /* + Driver for Philips tda8262/tda8263 DVBS Silicon tuners + + (c) 2006 Andrew de Quincey + + 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 <linux/module.h> +#include <linux/dvb/frontend.h> +#include <asm/types.h> + +#include "tda826x.h" + +static int debug = 0; +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG "tda826x: " args); \ + } while (0) + +struct tda826x_priv { + /* i2c details */ + int i2c_address; + struct i2c_adapter *i2c; + u8 has_loopthrough:1; + u32 frequency; +}; + +static int tda826x_release(struct dvb_frontend *fe) +{ + if (fe->tuner_priv) + kfree(fe->tuner_priv); + fe->tuner_priv = NULL; + return 0; +} + +static int tda826x_sleep(struct dvb_frontend *fe) +{ + struct tda826x_priv *priv = fe->tuner_priv; + int ret; + u8 buf [] = { 0x00, 0x8d }; + struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 }; + + dprintk("%s:\n", __FUNCTION__); + + if (!priv->has_loopthrough) + buf[1] = 0xad; + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { + dprintk("%s: i2c error\n", __FUNCTION__); + } + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + return (ret == 1) ? 0 : ret; +} + +static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) +{ + struct tda826x_priv *priv = fe->tuner_priv; + int ret; + u32 div; + u8 buf [11]; + struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 }; + + dprintk("%s:\n", __FUNCTION__); + + div = (params->frequency + (1000-1)) / 1000; + + buf[0] = 0x00; // subaddress + buf[1] = 0x09; // powerdown RSSI + the magic value 1 + if (!priv->has_loopthrough) + buf[1] |= 0x20; // power down loopthrough if not needed + buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO + buf[3] = div >> 7; + buf[4] = div << 1; + buf[5] = 0xff; // basedband filter to max + buf[6] = 0xfe; // gains at max + no RF attenuation + buf[7] = 0x83; // charge pumps at high, tests off + buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports. + buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL + buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) { + dprintk("%s: i2c error\n", __FUNCTION__); + } + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + priv->frequency = div * 1000; + + return (ret == 1) ? 0 : ret; +} + +static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency) +{ + struct tda826x_priv *priv = fe->tuner_priv; + *frequency = priv->frequency; + return 0; +} + +static struct dvb_tuner_ops tda826x_tuner_ops = { + .info = { + .name = "Philips TDA826X", + .frequency_min = 950000, + .frequency_min = 2175000 + }, + .release = tda826x_release, + .sleep = tda826x_sleep, + .set_params = tda826x_set_params, + .get_frequency = tda826x_get_frequency, +}; + +struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough) +{ + struct tda826x_priv *priv = NULL; + u8 b1 [] = { 0, 0 }; + struct i2c_msg msg [] = { { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } }; + int ret; + + dprintk("%s:\n", __FUNCTION__); + + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 1); + ret = i2c_transfer (i2c, msg, 1); + if (fe->ops.i2c_gate_ctrl) + fe->ops.i2c_gate_ctrl(fe, 0); + + if (ret != 2) + return NULL; + if (!(b1[1] & 0x80)) + return NULL; + + priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL); + if (priv == NULL) + return NULL; + + priv->i2c_address = addr; + priv->i2c = i2c; + priv->has_loopthrough = has_loopthrough; + + memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops)); + + fe->tuner_priv = priv; + + return fe; +} +EXPORT_SYMBOL(tda826x_attach); + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); + +MODULE_DESCRIPTION("DVB TDA826x driver"); +MODULE_AUTHOR("Andrew de Quincey"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/tda826x.h b/linux/drivers/media/dvb/frontends/tda826x.h new file mode 100644 index 000000000..330760763 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/tda826x.h @@ -0,0 +1,40 @@ + /* + Driver for Philips tda8262/tda8263 DVBS Silicon tuners + + (c) 2006 Andrew de Quincey + + 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_TDA826X_H__ +#define __DVB_TDA826X_H__ + +#include <linux/i2c.h> +#include "dvb_frontend.h" + +/** + * Attach a tda826x tuner to the supplied frontend structure. + * + * @param fe Frontend to attach to. + * @param addr i2c address of the tuner. + * @param i2c i2c adapter to use. + * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector. + * @return FE pointer on success, NULL on failure. + */ +extern struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough); + +#endif diff --git a/linux/drivers/media/dvb/ttpci/Kconfig b/linux/drivers/media/dvb/ttpci/Kconfig index 0f01b9ff1..cca27777e 100644 --- a/linux/drivers/media/dvb/ttpci/Kconfig +++ b/linux/drivers/media/dvb/ttpci/Kconfig @@ -68,6 +68,8 @@ config DVB_BUDGET select DVB_TDA8083 if !DVB_FE_CUSTOMISE select DVB_TDA10021 if !DVB_FE_CUSTOMISE select DVB_S5H1420 if !DVB_FE_CUSTOMISE + select DVB_TDA10086 if !DVB_FE_CUSTOMISE + select DVB_TDA826X if !DVB_FE_CUSTOMISE select DVB_LNBP21 if !DVB_FE_CUSTOMISE help Support for simple SAA7146 based DVB cards diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c index e440fa100..2c4089cab 100644 --- a/linux/drivers/media/dvb/ttpci/budget-ci.c +++ b/linux/drivers/media/dvb/ttpci/budget-ci.c @@ -1046,8 +1046,7 @@ static void frontend_init(struct budget_ci *budget_ci) budget_ci->budget.dvb_frontend->ops.dishnetwork_send_legacy_command = NULL; if (dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, LNBP21_LLC, 0) == NULL) { printk("%s: No LNBP21 found!\n", __FUNCTION__); - if (budget_ci->budget.dvb_frontend->ops.release) - budget_ci->budget.dvb_frontend->ops.release(budget_ci->budget.dvb_frontend); + dvb_frontend_detach(budget_ci->budget.dvb_frontend); budget_ci->budget.dvb_frontend = NULL; } } diff --git a/linux/drivers/media/dvb/ttpci/budget.c b/linux/drivers/media/dvb/ttpci/budget.c index e846b9620..886eb6a27 100644 --- a/linux/drivers/media/dvb/ttpci/budget.c +++ b/linux/drivers/media/dvb/ttpci/budget.c @@ -41,6 +41,8 @@ #include "l64781.h" #include "tda8083.h" #include "s5h1420.h" +#include "tda10086.h" +#include "tda826x.h" #include "lnbp21.h" #include "bsru6.h" @@ -342,6 +344,11 @@ static struct s5h1420_config s5h1420_config = { .invert = 1, }; +static struct tda10086_config tda10086_config = { + .demod_address = 0x0e, + .invert = 0, +}; + static u8 read_pwm(struct budget* budget) { u8 b = 0xff; @@ -420,7 +427,25 @@ static void frontend_init(struct budget *budget) budget->dvb_frontend = dvb_attach(s5h1420_attach, &s5h1420_config, &budget->i2c_adap); if (budget->dvb_frontend) { budget->dvb_frontend->ops.tuner_ops.set_params = s5h1420_tuner_set_params; - if (lnbp21_attach(budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { + if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { + printk("%s: No LNBP21 found!\n", __FUNCTION__); + goto error_out; + } + break; + } + + case 0x1018: // TT Budget-S-1401 (philips tda10086/philips tda8262) + // gpio2 is connected to CLB - reset it + leave it high + saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTLO); + msleep(1); + saa7146_setgpio(budget->dev, 2, SAA7146_GPIO_OUTHI); + msleep(1); + + budget->dvb_frontend = dvb_attach(tda10086_attach, &tda10086_config, &budget->i2c_adap); + if (budget->dvb_frontend) { + if (dvb_attach(tda826x_attach, budget->dvb_frontend, 0x60, &budget->i2c_adap, 0) == NULL) + printk("%s: No tda826x found!\n", __FUNCTION__); + if (dvb_attach(lnbp21_attach, budget->dvb_frontend, &budget->i2c_adap, 0, 0) == NULL) { printk("%s: No LNBP21 found!\n", __FUNCTION__); goto error_out; } @@ -499,6 +524,7 @@ MAKE_BUDGET_INFO(ttbs, "TT-Budget/WinTV-NOVA-S PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbc, "TT-Budget/WinTV-NOVA-C PCI", BUDGET_TT); MAKE_BUDGET_INFO(ttbt, "TT-Budget/WinTV-NOVA-T PCI", BUDGET_TT); MAKE_BUDGET_INFO(satel, "SATELCO Multimedia PCI", BUDGET_TT_HW_DISEQC); +MAKE_BUDGET_INFO(ttbs1401, "TT-Budget-S-1401 PCI", BUDGET_TT); MAKE_BUDGET_INFO(fsacs0, "Fujitsu Siemens Activy Budget-S PCI (rev GR/grundig frontend)", BUDGET_FS_ACTIVY); MAKE_BUDGET_INFO(fsacs1, "Fujitsu Siemens Activy Budget-S PCI (rev AL/alps frontend)", BUDGET_FS_ACTIVY); @@ -508,6 +534,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(ttbt, 0x13c2, 0x1005), MAKE_EXTENSION_PCI(satel, 0x13c2, 0x1013), MAKE_EXTENSION_PCI(ttbs, 0x13c2, 0x1016), + MAKE_EXTENSION_PCI(ttbs1401, 0x13c2, 0x1018), MAKE_EXTENSION_PCI(fsacs1,0x1131, 0x4f60), MAKE_EXTENSION_PCI(fsacs0,0x1131, 0x4f61), { diff --git a/linux/drivers/media/dvb/ttusb-budget/Kconfig b/linux/drivers/media/dvb/ttusb-budget/Kconfig index ce0fb8f54..f546bccdb 100644 --- a/linux/drivers/media/dvb/ttusb-budget/Kconfig +++ b/linux/drivers/media/dvb/ttusb-budget/Kconfig @@ -1,6 +1,6 @@ config DVB_TTUSB_BUDGET tristate "Technotrend/Hauppauge Nova-USB devices" - depends on DVB_CORE && USB + depends on DVB_CORE && USB && I2C select DVB_CX22700 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_VES1820 if !DVB_FE_CUSTOMISE diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index f43f5a21a..7015517e2 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -7,7 +7,7 @@ menu "Radio Adapters" config RADIO_CADET tristate "ADS Cadet AM/FM Tuner" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these AM/FM radio cards, and then fill in the port address below. @@ -350,5 +350,15 @@ config RADIO_ZOLTRIX_PORT help Enter the I/O port of your Zoltrix radio card. -endmenu +config USB_DSBR + tristate "D-Link USB FM radio support (EXPERIMENTAL)" + depends on USB && VIDEO_V4L2 && EXPERIMENTAL + ---help--- + Say Y here if you want to connect this type of radio to your + computer's USB port. Note that the audio is not digital, and + you must connect the line out connector to a sound card or a + set of speakers. + To compile this driver as a module, choose M here: the + module will be called dsbr100. +endmenu diff --git a/linux/drivers/media/radio/Makefile b/linux/drivers/media/radio/Makefile index e95b6805e..cf55a18e3 100644 --- a/linux/drivers/media/radio/Makefile +++ b/linux/drivers/media/radio/Makefile @@ -20,5 +20,6 @@ obj-$(CONFIG_RADIO_GEMTEK) += radio-gemtek.o obj-$(CONFIG_RADIO_GEMTEK_PCI) += radio-gemtek-pci.o obj-$(CONFIG_RADIO_TRUST) += radio-trust.o obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o +obj-$(CONFIG_USB_DSBR) += dsbr100.o EXTRA_CFLAGS += -Isound diff --git a/linux/drivers/media/video/dsbr100.c b/linux/drivers/media/radio/dsbr100.c index 45d2b5028..c4e67e6c8 100644 --- a/linux/drivers/media/video/dsbr100.c +++ b/linux/drivers/media/radio/dsbr100.c @@ -33,8 +33,14 @@ History: + Version 0.41-ac1: + Alan Cox: Some cleanups and fixes + + Version 0.41: + Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> + Version 0.40: - Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing + Markus: Updates for 2.6.x kernels, code layout changes, name sanitizing Version 0.30: Markus: Updates for 2.5.x kernel and more ISO compliant source @@ -65,14 +71,13 @@ */ - #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/input.h> #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <media/v4l2-common.h> #include <linux/usb.h> #include <linux/smp_lock.h> @@ -80,7 +85,22 @@ /* * Version Information */ -#define DRIVER_VERSION "v0.40" +#include <linux/version.h> /* for KERNEL_VERSION MACRO */ + +#define DRIVER_VERSION "v0.41" +#define RADIO_VERSION KERNEL_VERSION(0,4,1) + +static struct v4l2_queryctrl radio_qctrl[] = { + { + .id = V4L2_CID_AUDIO_MUTE, + .name = "Mute", + .minimum = 0, + .maximum = 1, + .default_value = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + } +}; + #define DRIVER_AUTHOR "Markus Demleitner <msdemlei@tucana.harvard.edu>" #define DRIVER_DESC "D-Link DSB-R100 USB FM radio driver" @@ -112,7 +132,7 @@ static int radio_nr = -1; module_param(radio_nr, int, 0); /* Data for one (physical) device */ -typedef struct { +struct dsbr100_device { struct usb_device *usbdev; struct video_device *videodev; unsigned char transfer_buffer[TB_LEN]; @@ -120,7 +140,8 @@ typedef struct { int stereo; int users; int removed; -} dsbr100_device; + int muted; +}; /* File system interface */ @@ -139,7 +160,6 @@ static struct video_device dsbr100_videodev_template= .owner = THIS_MODULE, .name = "D-Link DSB-R 100", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_AZTECH, .fops = &usb_dsbr100_fops, .release = video_device_release, }; @@ -162,7 +182,7 @@ static struct usb_driver usb_dsbr100_driver = { /* Low-level device interface begins here */ /* switch on radio */ -static int dsbr100_start(dsbr100_device *radio) +static int dsbr100_start(struct dsbr100_device *radio) { if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, @@ -173,12 +193,13 @@ static int dsbr100_start(dsbr100_device *radio) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x01, 0x00, radio->transfer_buffer, 8, 300)<0) return -1; + radio->muted=0; return (radio->transfer_buffer)[0]; } /* switch off radio */ -static int dsbr100_stop(dsbr100_device *radio) +static int dsbr100_stop(struct dsbr100_device *radio) { if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, @@ -189,11 +210,12 @@ static int dsbr100_stop(dsbr100_device *radio) USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x00, 0x00, radio->transfer_buffer, 8, 300)<0) return -1; + radio->muted=1; return (radio->transfer_buffer)[0]; } /* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */ -static int dsbr100_setfreq(dsbr100_device *radio, int freq) +static int dsbr100_setfreq(struct dsbr100_device *radio, int freq) { freq = (freq/16*80)/1000+856; if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), @@ -218,7 +240,7 @@ static int dsbr100_setfreq(dsbr100_device *radio, int freq) /* return the device status. This is, in effect, just whether it sees a stereo signal or not. Pity. */ -static void dsbr100_getstat(dsbr100_device *radio) +static void dsbr100_getstat(struct dsbr100_device *radio) { if (usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), USB_REQ_GET_STATUS, @@ -237,9 +259,9 @@ usb if it is */ static int usb_dsbr100_probe(struct usb_interface *intf, const struct usb_device_id *id) { - dsbr100_device *radio; + struct dsbr100_device *radio; - if (!(radio = kmalloc(sizeof(dsbr100_device), GFP_KERNEL))) + if (!(radio = kmalloc(sizeof(struct dsbr100_device), GFP_KERNEL))) return -ENOMEM; if (!(radio->videodev = video_device_alloc())) { kfree(radio); @@ -272,7 +294,7 @@ code I'd expect I better did that, but if there's a memory leak here it's tiny (~50 bytes per disconnect) */ static void usb_dsbr100_disconnect(struct usb_interface *intf) { - dsbr100_device *radio = usb_get_intfdata(intf); + struct dsbr100_device *radio = usb_get_intfdata(intf); usb_set_intfdata (intf, NULL); if (radio) { @@ -292,89 +314,121 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf) static int usb_dsbr100_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { - dsbr100_device *radio=video_get_drvdata(video_devdata(file)); + struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); if (!radio) return -EIO; switch(cmd) { - case VIDIOCGCAP: { - struct video_capability *v = arg; - - memset(v, 0, sizeof(*v)); - v->type = VID_TYPE_TUNER; - v->channels = 1; - v->audios = 1; - strcpy(v->name, "D-Link R-100 USB FM Radio"); + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *v = arg; + memset(v,0,sizeof(*v)); + strlcpy(v->driver, "dsbr100", sizeof (v->driver)); + strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: { - struct video_tuner *v = arg; + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *v = arg; - dsbr100_getstat(radio); - if(v->tuner) /* Only 1 tuner */ + if (v->index > 0) return -EINVAL; + + dsbr100_getstat(radio); + + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + v->rangelow = FREQ_MIN*FREQ_MUL; v->rangehigh = FREQ_MAX*FREQ_MUL; - v->flags = VIDEO_TUNER_LOW; - v->mode = VIDEO_MODE_AUTO; - v->signal = radio->stereo*0x7000; - /* Don't know how to get signal strength */ - v->flags |= VIDEO_TUNER_STEREO_ON*radio->stereo; - strcpy(v->name, "DSB R-100"); - return 0; - } - case VIDIOCSTUNER: { - struct video_tuner *v = arg; + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; + if(radio->stereo) + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal = 0xFFFF; /* We can't get the signal strength */ - if(v->tuner!=0) - return -EINVAL; - /* Only 1 tuner so no setting needed ! */ return 0; } - case VIDIOCGFREQ: { - int *freq = arg; + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *v = arg; - if (radio->curfreq==-1) + if (v->index > 0) return -EINVAL; - *freq = radio->curfreq; + return 0; } - case VIDIOCSFREQ: { - int *freq = arg; + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; - radio->curfreq = *freq; + radio->curfreq = f->frequency; if (dsbr100_setfreq(radio, radio->curfreq)==-1) warn("Set frequency failed"); return 0; } - case VIDIOCGAUDIO: { - struct video_audio *v = arg; - - memset(v, 0, sizeof(*v)); - v->flags |= VIDEO_AUDIO_MUTABLE; - v->mode = VIDEO_SOUND_STEREO; - v->volume = 1; - v->step = 1; - strcpy(v->name, "Radio"); + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = radio->curfreq; + return 0; } - case VIDIOCSAUDIO: { - struct video_audio *v = arg; - - if (v->audio) - return -EINVAL; - if (v->flags&VIDEO_AUDIO_MUTE) { - if (dsbr100_stop(radio)==-1) - warn("Radio did not respond properly"); + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qc = arg; + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if (qc->id && qc->id == radio_qctrl[i].id) { + memcpy(qc, &(radio_qctrl[i]), + sizeof(*qc)); + return 0; + } } - else - if (dsbr100_start(radio)==-1) - warn("Radio did not respond properly"); - return 0; + return -EINVAL; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=radio->muted; + return 0; + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + if (dsbr100_stop(radio)==-1) + warn("Radio did not respond properly"); + } else { + if (dsbr100_start(radio)==-1) + warn("Radio did not respond properly"); + } + return 0; + } + return -EINVAL; } default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + usb_dsbr100_do_ioctl); } } @@ -386,9 +440,11 @@ static int usb_dsbr100_ioctl(struct inode *inode, struct file *file, static int usb_dsbr100_open(struct inode *inode, struct file *file) { - dsbr100_device *radio=video_get_drvdata(video_devdata(file)); + struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); radio->users = 1; + radio->muted = 1; + if (dsbr100_start(radio)<0) { warn("Radio did not start up properly"); radio->users = 0; @@ -400,7 +456,7 @@ static int usb_dsbr100_open(struct inode *inode, struct file *file) static int usb_dsbr100_close(struct inode *inode, struct file *file) { - dsbr100_device *radio=video_get_drvdata(video_devdata(file)); + struct dsbr100_device *radio=video_get_drvdata(video_devdata(file)); if (!radio) return -ENODEV; diff --git a/linux/drivers/media/radio/radio-cadet.c b/linux/drivers/media/radio/radio-cadet.c index bad7dcadc..fd7bc09fc 100644 --- a/linux/drivers/media/radio/radio-cadet.c +++ b/linux/drivers/media/radio/radio-cadet.c @@ -25,6 +25,9 @@ * * 2003-01-31 Alan Cox <alan@redhat.com> * Cleaned up locking, delay code, general odds and ends + * + * 2006-07-30 Hans J. Koch <koch@hjk-az.de> + * Changed API to V4L2 */ #include <linux/module.h> /* Modules */ @@ -34,12 +37,16 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* V4L2 API defs */ #include <media/v4l2-common.h> #include <linux/param.h> #include <linux/pnp.h> #define RDS_BUFFER 256 +#define RDS_RX_FLAG 1 +#define MBS_RX_FLAG 2 + +#define CADET_VERSION KERNEL_VERSION(0,3,3) static int io=-1; /* default to isapnp activation */ static int radio_nr = -1; @@ -62,9 +69,15 @@ static int cadet_probe(void); */ static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}}; -static int cadet_getrds(void) +#if 0 +/* +Note: cadet_getrds() is not used at the moment. It will be useful for future +extensions, e.g. an ioctl to query RDS reception quality. - Hans J. Koch +*/ +static int +cadet_getrds(void) { - int rdsstat=0; + int rds_mbs_stat=0; spin_lock(&cadet_io_lock); outb(3,io); /* Select Decoder Control/Status */ @@ -76,30 +89,33 @@ static int cadet_getrds(void) spin_lock(&cadet_io_lock); outb(3,io); /* Select Decoder Control/Status */ if((inb(io+1)&0x80)!=0) { - rdsstat|=VIDEO_TUNER_RDS_ON; + rds_mbs_stat |= RDS_RX_FLAG; } if((inb(io+1)&0x10)!=0) { - rdsstat|=VIDEO_TUNER_MBS_ON; + rds_mbs_stat |= MBS_RX_FLAG; } spin_unlock(&cadet_io_lock); - return rdsstat; + return rds_mbs_stat; } +#endif -static int cadet_getstereo(void) +static int +cadet_getstereo(void) { - int ret = 0; + int ret = V4L2_TUNER_SUB_MONO; if(curtuner != 0) /* Only FM has stereo capability! */ - return 0; + return V4L2_TUNER_SUB_MONO; spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ if( (inb(io+1) & 0x40) == 0) - ret = 1; + ret = V4L2_TUNER_SUB_STEREO; spin_unlock(&cadet_io_lock); return ret; } -static unsigned cadet_gettune(void) +static unsigned +cadet_gettune(void) { int curvol,i; unsigned fifo=0; @@ -136,7 +152,8 @@ static unsigned cadet_gettune(void) return fifo; } -static unsigned cadet_getfreq(void) +static unsigned +cadet_getfreq(void) { int i; unsigned freq=0,test,fifo=0; @@ -168,7 +185,8 @@ static unsigned cadet_getfreq(void) return freq; } -static void cadet_settune(unsigned fifo) +static void +cadet_settune(unsigned fifo) { int i; unsigned test; @@ -196,7 +214,8 @@ static void cadet_settune(unsigned fifo) spin_unlock(&cadet_io_lock); } -static void cadet_setfreq(unsigned freq) +static void +cadet_setfreq(unsigned freq) { unsigned fifo; int i,j,test; @@ -256,7 +275,8 @@ static void cadet_setfreq(unsigned freq) } -static int cadet_getvol(void) +static int +cadet_getvol(void) { int ret = 0; @@ -271,7 +291,8 @@ static int cadet_getvol(void) } -static void cadet_setvol(int vol) +static void +cadet_setvol(int vol) { spin_lock(&cadet_io_lock); outb(7,io); /* Select tuner control */ @@ -282,7 +303,8 @@ static void cadet_setvol(int vol) spin_unlock(&cadet_io_lock); } -static void cadet_handler(unsigned long data) +static void +cadet_handler(unsigned long data) { /* * Service the RDS fifo @@ -323,8 +345,8 @@ static void cadet_handler(unsigned long data) -static ssize_t cadet_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) +static ssize_t +cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { int i=0; unsigned char readbuf[RDS_BUFFER]; @@ -360,128 +382,156 @@ static int cadet_do_ioctl(struct inode *inode, struct file *file, { switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; - memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=2; - v->audios=1; - strcpy(v->name, "ADS Cadet"); + struct v4l2_capability *cap = arg; + memset(cap,0,sizeof(*cap)); + cap->capabilities = + V4L2_CAP_TUNER | + V4L2_CAP_READWRITE; + cap->version = CADET_VERSION; + strcpy(cap->driver, "ADS Cadet"); + strcpy(cap->card, "ADS Cadet"); return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if((v->tuner<0)||(v->tuner>1)) { - return -EINVAL; - } - switch(v->tuner) { - case 0: - strcpy(v->name,"FM"); - v->rangelow=1400; /* 87.5 MHz */ - v->rangehigh=1728; /* 108.0 MHz */ - v->flags=0; - v->mode=0; - v->mode|=VIDEO_MODE_AUTO; - v->signal=sigstrength; - if(cadet_getstereo()==1) { - v->flags|=VIDEO_TUNER_STEREO_ON; - } - v->flags|=cadet_getrds(); - break; - case 1: - strcpy(v->name,"AM"); - v->rangelow=8320; /* 520 kHz */ - v->rangehigh=26400; /* 1650 kHz */ - v->flags=0; - v->flags|=VIDEO_TUNER_LOW; - v->mode=0; - v->mode|=VIDEO_MODE_AUTO; - v->signal=sigstrength; - break; + struct v4l2_tuner *t = arg; + memset(t,0,sizeof(*t)); + t->type = V4L2_TUNER_RADIO; + switch (t->index) + { + case 0: strcpy(t->name, "FM"); + t->capability = V4L2_TUNER_CAP_STEREO; + t->rangelow = 1400; /* 87.5 MHz */ + t->rangehigh = 1728; /* 108.0 MHz */ + t->rxsubchans=cadet_getstereo(); + switch (t->rxsubchans){ + case V4L2_TUNER_SUB_MONO: + t->audmode = V4L2_TUNER_MODE_MONO; + break; + case V4L2_TUNER_SUB_STEREO: + t->audmode = V4L2_TUNER_MODE_STEREO; + break; + default: ; + } + break; + case 1: strcpy(t->name, "AM"); + t->capability = V4L2_TUNER_CAP_LOW; + t->rangelow = 8320; /* 520 kHz */ + t->rangehigh = 26400; /* 1650 kHz */ + t->rxsubchans = V4L2_TUNER_SUB_MONO; + t->audmode = V4L2_TUNER_MODE_MONO; + break; + default: + return -EINVAL; } + + t->signal = sigstrength; /* We might need to modify scaling of this */ return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if((v->tuner<0)||(v->tuner>1)) { + struct v4l2_tuner *t = arg; + if((t->index != 0)&&(t->index != 1)) return -EINVAL; - } - curtuner=v->tuner; + + curtuner = t->index; return 0; } - case VIDIOCGFREQ: + case VIDIOC_G_FREQUENCY: { - unsigned long *freq = arg; - *freq = cadet_getfreq(); + struct v4l2_frequency *f = arg; + memset(f,0,sizeof(*f)); + f->tuner = curtuner; + f->type = V4L2_TUNER_RADIO; + f->frequency = cadet_getfreq(); return 0; } - case VIDIOCSFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - if((curtuner==0)&&((*freq<1400)||(*freq>1728))) { + struct v4l2_frequency *f = arg; + if (f->type != V4L2_TUNER_RADIO){ + return -EINVAL; + } + if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728))) { return -EINVAL; } - if((curtuner==1)&&((*freq<8320)||(*freq>26400))) { + if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400))) { return -EINVAL; } - cadet_setfreq(*freq); + cadet_setfreq(f->frequency); return 0; } - case VIDIOCGAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; - if(cadet_getstereo()==0) { - v->mode=VIDEO_SOUND_MONO; - } else { - v->mode=VIDEO_SOUND_STEREO; + struct v4l2_control *c = arg; + switch (c->id){ + case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ + c->value = (cadet_getvol() == 0); + break; + case V4L2_CID_AUDIO_VOLUME: + c->value = cadet_getvol(); + break; + default: + return -EINVAL; } - v->volume=cadet_getvol(); - v->step=0xffff; - strcpy(v->name, "Radio"); return 0; } - case VIDIOCSAUDIO: + case VIDIOC_S_CTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - cadet_setvol(v->volume); - if(v->flags&VIDEO_AUDIO_MUTE) - cadet_setvol(0); - else - cadet_setvol(0xffff); + struct v4l2_control *c = arg; + switch (c->id){ + case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */ + if (c->value) cadet_setvol(0); + else cadet_setvol(0xffff); + break; + case V4L2_CID_AUDIO_VOLUME: + cadet_setvol(c->value); + break; + default: + return -EINVAL; + } return 0; } + default: return -ENOIOCTLCMD; } } -static int cadet_ioctl(struct inode *inode, struct file *file, +static int +cadet_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(inode, file, cmd, arg, cadet_do_ioctl); } -static int cadet_open(struct inode *inode, struct file *file) +static int +cadet_open(struct inode *inode, struct file *file) { - if(users) - return -EBUSY; users++; - init_waitqueue_head(&read_queue); + if (1 == users) init_waitqueue_head(&read_queue); return 0; } -static int cadet_release(struct inode *inode, struct file *file) +static int +cadet_release(struct inode *inode, struct file *file) { - del_timer_sync(&readtimer); - rdsstat=0; users--; + if (0 == users){ + del_timer_sync(&readtimer); + rdsstat=0; + } + return 0; +} + +static unsigned int +cadet_poll(struct file *file, struct poll_table_struct *wait) +{ + poll_wait(file,&read_queue,wait); + if(rdsin != rdsout) + return POLLIN | POLLRDNORM; return 0; } @@ -492,6 +542,7 @@ static struct file_operations cadet_fops = { .release = cadet_release, .read = cadet_read, .ioctl = cadet_ioctl, + .poll = cadet_poll, .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -501,7 +552,6 @@ static struct video_device cadet_radio= .owner = THIS_MODULE, .name = "Cadet radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_CADET, .fops = &cadet_fops, }; diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index fe56862d5..732bf1e7c 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -449,18 +449,6 @@ source "drivers/media/video/pvrusb2/Kconfig" source "drivers/media/video/em28xx/Kconfig" -config USB_DSBR - tristate "D-Link USB FM radio support (EXPERIMENTAL)" - depends on USB && VIDEO_V4L1 && EXPERIMENTAL - ---help--- - Say Y here if you want to connect this type of radio to your - computer's USB port. Note that the audio is not digital, and - you must connect the line out connector to a sound card or a - set of speakers. - - To compile this driver as a module, choose M here: the - module will be called dsbr100. - source "drivers/media/video/usbvideo/Kconfig" source "drivers/media/video/et61x251/Kconfig" diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 353d61cfa..010833d81 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -77,7 +77,6 @@ obj-$(CONFIG_VIDEO_UPD64083) += upd64083.o obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o obj-$(CONFIG_USB_DABUSB) += dabusb.o -obj-$(CONFIG_USB_DSBR) += dsbr100.o obj-$(CONFIG_USB_OV511) += ov511.o obj-$(CONFIG_USB_SE401) += se401.o obj-$(CONFIG_USB_STV680) += stv680.o diff --git a/linux/drivers/media/video/compat_ioctl32.c b/linux/drivers/media/video/compat_ioctl32.c index 0e8c63c18..8e80a76ec 100644 --- a/linux/drivers/media/video/compat_ioctl32.c +++ b/linux/drivers/media/video/compat_ioctl32.c @@ -23,7 +23,7 @@ #ifdef CONFIG_COMPAT - +#ifdef CONFIG_VIDEO_V4L1_COMPAT struct video_tuner32 { compat_int_t tuner; char name[32]; @@ -109,6 +109,7 @@ struct video_window32 { compat_caddr_t clips; compat_int_t clipcount; }; +#endif static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -126,6 +127,7 @@ static int native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* You get back everything except the clips... */ static int put_video_window32(struct video_window *kp, struct video_window32 __user *up) { @@ -140,6 +142,7 @@ static int put_video_window32(struct video_window *kp, struct video_window32 __u return -EFAULT; return 0; } +#endif struct v4l2_clip32 { @@ -492,6 +495,7 @@ static inline int put_v4l2_input(struct v4l2_input *kp, struct v4l2_input __user return 0; } +#ifdef CONFIG_VIDEO_V4L1_COMPAT struct video_code32 { char loadwhat[16]; /* name or tag of file being passed */ @@ -519,6 +523,8 @@ static inline int microcode32(struct video_code *kp, struct video_code32 __user #define VIDIOCSFREQ32 _IOW('v',15, u32) #define VIDIOCSMICROCODE32 _IOW('v',27, struct video_code32) +#endif + /* VIDIOC_ENUMINPUT32 is VIDIOC_ENUMINPUT minus 4 bytes of padding alignement */ #define VIDIOC_ENUMINPUT32 VIDIOC_ENUMINPUT - _IOC(0, 0, 0, 4) #define VIDIOC_G_FMT32 _IOWR ('V', 4, struct v4l2_format32) @@ -539,6 +545,7 @@ static inline int microcode32(struct video_code *kp, struct video_code32 __user #define VIDIOC_S_INPUT32 _IOWR ('V', 39, compat_int_t) #define VIDIOC_TRY_FMT32 _IOWR ('V', 64, struct v4l2_format32) +#ifdef CONFIG_VIDEO_V4L1_COMPAT enum { MaxClips = (~0U-sizeof(struct video_window))/sizeof(struct video_clip) }; @@ -603,14 +610,17 @@ static int do_set_window(struct file *file, unsigned int cmd, unsigned long arg) return native_ioctl(file, VIDIOCSWIN, (unsigned long)vw); } +#endif static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { union { +#ifdef CONFIG_VIDEO_V4L1_COMPAT struct video_tuner vt; struct video_buffer vb; struct video_window vw; struct video_code vc; +#endif struct v4l2_format v2f; struct v4l2_buffer v2b; struct v4l2_framebuffer v2fb; @@ -626,6 +636,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg /* First, convert the command. */ switch(cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGTUNER32: cmd = VIDIOCGTUNER; break; case VIDIOCSTUNER32: cmd = VIDIOCSTUNER; break; case VIDIOCGWIN32: cmd = VIDIOCGWIN; break; @@ -633,6 +644,8 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOCSFBUF32: cmd = VIDIOCSFBUF; break; case VIDIOCGFREQ32: cmd = VIDIOCGFREQ; break; case VIDIOCSFREQ32: cmd = VIDIOCSFREQ; break; + case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; +#endif case VIDIOC_G_FMT32: cmd = VIDIOC_G_FMT; break; case VIDIOC_S_FMT32: cmd = VIDIOC_S_FMT; break; case VIDIOC_QUERYBUF32: cmd = VIDIOC_QUERYBUF; break; @@ -649,10 +662,10 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; case VIDIOC_TRY_FMT32: cmd = VIDIOC_TRY_FMT; break; - case VIDIOCSMICROCODE32: cmd = VIDIOCSMICROCODE; break; }; switch(cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSTUNER: case VIDIOCGTUNER: err = get_video_tuner32(&karg.vt, up); @@ -666,6 +679,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg break; case VIDIOCSFREQ: +#endif case VIDIOC_S_INPUT: case VIDIOC_OVERLAY: case VIDIOC_STREAMON: @@ -719,18 +733,21 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg compatible_arg = 0; break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGWIN: case VIDIOCGFBUF: case VIDIOCGFREQ: +#endif case VIDIOC_G_FBUF: case VIDIOC_G_INPUT: compatible_arg = 0; +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSMICROCODE: err = microcode32(&karg.vc, up); compatible_arg = 0; break; +#endif }; - if(err) goto out; @@ -745,6 +762,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg } if(err == 0) { switch(cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGTUNER: err = put_video_tuner32(&karg.vt, up); break; @@ -756,7 +774,7 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg case VIDIOCGFBUF: err = put_video_buffer32(&karg.vb, up); break; - +#endif case VIDIOC_G_FBUF: err = put_v4l2_framebuffer32(&karg.v2fb, up); break; @@ -794,7 +812,9 @@ static int do_video_ioctl(struct file *file, unsigned int cmd, unsigned long arg err = put_v4l2_input32(&karg.v2i, up); break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGFREQ: +#endif case VIDIOC_G_INPUT: err = put_user(((u32)karg.vx), (u32 __user *)up); break; @@ -812,6 +832,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) return ret; switch (cmd) { +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSWIN32: ret = do_set_window(file, cmd, arg); break; @@ -822,6 +843,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOCSFBUF32: case VIDIOCGFREQ32: case VIDIOCSFREQ32: +#endif case VIDIOC_QUERYCAP: case VIDIOC_ENUM_FMT: case VIDIOC_G_FMT32: @@ -853,6 +875,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) ret = do_video_ioctl(file, cmd, arg); break; +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* Little v, the video4linux ioctls (conflict?) */ case VIDIOCGCAP: case VIDIOCGCHAN: @@ -881,6 +904,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case _IOR('v' , BASE_VIDIOCPRIVATE+7, int): ret = native_ioctl(file, cmd, (unsigned long)compat_ptr(arg)); break; +#endif default: v4l_print_ioctl("compat_ioctl32", cmd); } diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index b8793928a..1aef0005e 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1484,7 +1484,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_format *f = arg; return cx8800_try_fmt(dev,fh,f); } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* --- streaming capture ------------------------------------- */ case VIDIOCGMBUF: { @@ -1873,7 +1873,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, *id = 0; return 0; } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCSTUNER: { struct video_tuner *v = arg; diff --git a/linux/drivers/media/video/pwc/Kconfig b/linux/drivers/media/video/pwc/Kconfig index 697145e0b..8fdf7101d 100644 --- a/linux/drivers/media/video/pwc/Kconfig +++ b/linux/drivers/media/video/pwc/Kconfig @@ -30,7 +30,7 @@ config USB_PWC config USB_PWC_DEBUG bool "USB Philips Cameras verbose debug" - depends USB_PWC + depends on USB_PWC help Say Y here in order to have the pwc driver generate verbose debugging messages. diff --git a/linux/drivers/media/video/saa7134/Kconfig b/linux/drivers/media/video/saa7134/Kconfig index 7c626cc1d..561599999 100644 --- a/linux/drivers/media/video/saa7134/Kconfig +++ b/linux/drivers/media/video/saa7134/Kconfig @@ -43,6 +43,9 @@ config VIDEO_SAA7134_DVB select DVB_MT352 if !DVB_FE_CUSTOMISE select DVB_TDA1004X if !DVB_FE_CUSTOMISE select DVB_NXT200X if !DVB_FE_CUSTOMISE + select DVB_TDA10086 if !DVB_FE_CUSTOMISE + select DVB_TDA826X if !DVB_FE_CUSTOMISE + select DVB_ISL6421 if !DVB_FE_CUSTOMISE ---help--- This adds support for DVB cards based on the Philips saa7134 chip. diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c index f1bdc1eab..4d2acfa48 100644 --- a/linux/drivers/media/video/saa7134/saa7134-cards.c +++ b/linux/drivers/media/video/saa7134/saa7134-cards.c @@ -2954,6 +2954,27 @@ struct saa7134_board saa7134_boards[] = { .amux = LINE2, }}, }, + [SAA7134_BOARD_FLYDVBS_LR300] = { + /* LifeView FlyDVB-s */ + /* Igor M. Liplianin <liplianin@tut.by> */ + .name = "LifeView FlyDVB-S /Acorp TV134DS", + .audio_clock = 0x00200000, + .tuner_type = TUNER_ABSENT, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .mpeg = SAA7134_MPEG_DVB, + .inputs = {{ + .name = name_comp1, /* Composite input */ + .vmux = 3, + .amux = LINE1, + },{ + .name = name_svideo, /* S-Video signal on S-Video input */ + .vmux = 8, + .amux = LINE1, + }}, + }, + }; const unsigned int saa7134_bcount = ARRAY_SIZE(saa7134_boards); @@ -3485,6 +3506,18 @@ struct pci_device_id saa7134_pci_tbl[] = { .subdevice = 0x0005, .driver_data = SAA7134_BOARD_MD7134_BRIDGE_2, },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x5168, + .subdevice = 0x0300, + .driver_data = SAA7134_BOARD_FLYDVBS_LR300, + },{ + .vendor = PCI_VENDOR_ID_PHILIPS, + .device = PCI_DEVICE_ID_PHILIPS_SAA7134, + .subvendor = 0x4e42, + .subdevice = 0x0300,/* LR300 */ + .driver_data = SAA7134_BOARD_FLYDVBS_LR300, + },{ .vendor = PCI_VENDOR_ID_PHILIPS, .device = PCI_DEVICE_ID_PHILIPS_SAA7134, .subvendor = 0x1489, @@ -3674,6 +3707,11 @@ int saa7134_board_init1(struct saa7134_dev *dev) case SAA7134_BOARD_FLYDVBTDUO: dev->has_remote = SAA7134_REMOTE_GPIO; break; + case SAA7134_BOARD_FLYDVBS_LR300: + saa_writeb(SAA7134_GPIO_GPMODE3, 0x80); + saa_writeb(SAA7134_GPIO_GPSTATUS2, 0x40); + dev->has_remote = SAA7134_REMOTE_GPIO; + break; case SAA7134_BOARD_MD5044: printk("%s: seems there are two different versions of the MD5044\n" "%s: (with the same ID) out there. If sound doesn't work for\n" diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c index 10253c935..a881085af 100644 --- a/linux/drivers/media/video/saa7134/saa7134-dvb.c +++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c @@ -40,6 +40,9 @@ #include "tda1004x.h" #include "nxt200x.h" +#include "tda10086.h" +#include "tda826x.h" +#include "isl6421.h" MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); MODULE_LICENSE("GPL"); @@ -1003,6 +1006,11 @@ static struct tda1004x_config md8800_dvbt_config = { .request_firmware = NULL, }; +static struct tda10086_config flydvbs = { + .demod_address = 0x0e, + .invert = 0, +}; + /* ------------------------------------------------------------------ */ static struct nxt200x_config avertvhda180 = { @@ -1200,6 +1208,17 @@ static int dvb_init(struct saa7134_dev *dev) dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, &dev->i2c_adap, &dvb_pll_tuv1236d); } break; + case SAA7134_BOARD_FLYDVBS_LR300: + dev->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, &dev->i2c_adap); + if (dev->dvb.frontend) { + if (dvb_attach(tda826x_attach, dev->dvb.frontend, 0x60, &dev->i2c_adap, 0) == NULL) { + printk("%s: No tda826x found!\n", __FUNCTION__); + } + if (dvb_attach(isl6421_attach, dev->dvb.frontend, &dev->i2c_adap, 0x08, 0, 0) == NULL) { + printk("%s: No ISL6421 found!\n", __FUNCTION__); + } + } + break; default: printk("%s: Huh? unknown DVB card?\n",dev->name); break; diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index bca987bef..3a2fde062 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -2095,7 +2095,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file, struct v4l2_format *f = arg; return saa7134_try_fmt(dev,fh,f); } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT case VIDIOCGMBUF: { struct video_mbuf *mbuf = arg; diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index b5eed7a9e..a913b6e28 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -233,6 +233,7 @@ struct saa7134_format { #define SAA7134_BOARD_FLYDVBT_HYBRID_CARDBUS 94 #define SAA7134_BOARD_FLYVIDEO3000_NTSC 95 #define SAA7134_BOARD_MEDION_MD8800_QUADRO 96 +#define SAA7134_BOARD_FLYDVBS_LR300 97 #define SAA7134_MAXBOARDS 8 #define SAA7134_INPUT_MAX 8 diff --git a/linux/drivers/media/video/usbvideo/konicawc.c b/linux/drivers/media/video/usbvideo/konicawc.c index 1feaf5f0b..8c0e25fde 100644 --- a/linux/drivers/media/video/usbvideo/konicawc.c +++ b/linux/drivers/media/video/usbvideo/konicawc.c @@ -228,6 +228,7 @@ static void konicawc_adjust_picture(struct uvd *uvd) static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev) { struct input_dev *input_dev; + int error; usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname)); strncat(cam->input_physname, "/input0", sizeof(cam->input_physname)); @@ -248,7 +249,13 @@ static void konicawc_register_input(struct konicawc *cam, struct usb_device *dev input_dev->private = cam; - input_register_device(cam->input); + error = input_register_device(cam->input); + if (error) { + warn("Failed to register camera's input device, err: %d\n", + error); + input_free_device(cam->input); + cam->input = NULL; + } } static void konicawc_unregister_input(struct konicawc *cam) diff --git a/linux/drivers/media/video/v4l2-common.c b/linux/drivers/media/video/v4l2-common.c index deb2a98c9..47b932809 100644 --- a/linux/drivers/media/video/v4l2-common.c +++ b/linux/drivers/media/video/v4l2-common.c @@ -220,7 +220,7 @@ static char *v4l2_memory_names[] = { /* ------------------------------------------------------------------ */ /* debug help functions */ -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT static const char *v4l1_ioctls[] = { [_IOC_NR(VIDIOCGCAP)] = "VIDIOCGCAP", [_IOC_NR(VIDIOCGCHAN)] = "VIDIOCGCHAN", @@ -321,7 +321,7 @@ static const char *v4l2_ioctls[] = { #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) static const char *v4l2_int_ioctls[] = { -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", @@ -387,7 +387,7 @@ void v4l_printk_ioctl(unsigned int cmd) (_IOC_NR(cmd) < V4L2_INT_IOCTLS) ? v4l2_int_ioctls[_IOC_NR(cmd)] : "UNKNOWN", dir, cmd); break; -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT case 'v': printk("v4l1 ioctl %s, dir=%s (0x%08x)\n", (_IOC_NR(cmd) < V4L1_IOCTLS) ? diff --git a/linux/drivers/media/video/videodev.c b/linux/drivers/media/video/videodev.c index 4ac9eb21a..b5fd2eabf 100644 --- a/linux/drivers/media/video/videodev.c +++ b/linux/drivers/media/video/videodev.c @@ -779,7 +779,7 @@ static int __video_do_ioctl(struct inode *inode, struct file *file, ret=vfd->vidioc_overlay(file, fh, *i); break; } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT /* --- streaming capture ------------------------------------- */ case VIDIOCGMBUF: { diff --git a/linux/drivers/media/video/vivi.c b/linux/drivers/media/video/vivi.c index 0a75f4bda..de72ebf74 100644 --- a/linux/drivers/media/video/vivi.c +++ b/linux/drivers/media/video/vivi.c @@ -1062,7 +1062,7 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *p) file->f_flags & O_NONBLOCK)); } -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT static int vidiocgmbuf (struct file *file, void *priv, struct video_mbuf *mbuf) { struct vivi_fh *fh=priv; @@ -1410,7 +1410,7 @@ static struct video_device vivi = { .vidioc_s_ctrl = vidioc_s_ctrl, .vidioc_streamon = vidioc_streamon, .vidioc_streamoff = vidioc_streamoff, -#ifdef CONFIG_V4L1_COMPAT +#ifdef CONFIG_VIDEO_V4L1_COMPAT .vidiocgmbuf = vidiocgmbuf, #endif .tvnorms = tvnorms, diff --git a/v4l/Makefile b/v4l/Makefile index 63d3fe48a..3e9336a95 100644 --- a/v4l/Makefile +++ b/v4l/Makefile @@ -33,7 +33,7 @@ endif default:: config-compat.h Makefile.media links .version echo srcdir $(SRCDIR) $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MYCFLAGS) modules - + ./scripts/rmmod.pl check ################################################# # Object specific rules diff --git a/v4l/scripts/make_kconfig.pl b/v4l/scripts/make_kconfig.pl index 771efa63d..e34a26f17 100755 --- a/v4l/scripts/make_kconfig.pl +++ b/v4l/scripts/make_kconfig.pl @@ -26,10 +26,6 @@ sub process_config ($) open $in,"$kernel/include/$filename" or die "File not found: $kernel/include/$filename"; while (<$in>) { - if (m|\#include\s+\<(.*)\>|) { - process_config ($1); - next; - } if (m/\#define\s+CONFIG_([^ ]*)_ON_SMP\s+(.*)\n/) { my $key=$1; my $value=$2; @@ -229,10 +225,10 @@ sub open_kconfig($$) { open_kconfig($dir,"$dir/$1"); next; } - if (m|^\s+depends on\s+(.*)\n|) { + if (m|^\s+depends on\s+(.+?)\s*$|) { check_deps ($key,$1); } - if (m|^\s+select\s+(.*)\n|) { + if (m|^\s+select\s+(.+?)\s*(if .*?)?\s*$|) { check_deps ($key,$1); } if (m|^\s+bool(ean)?\s|) { @@ -333,7 +329,7 @@ sub cmp_ver($$) return $v1_sublevel <=> $v2_sublevel; } -process_config("linux/config.h"); +process_config("linux/autoconf.h"); parse_versions; @@ -402,13 +398,14 @@ close OUT; # These options should default to off disable_config('DVB_AV7110_FIRMWARE'); disable_config('DVB_CINERGYT2_TUNING'); +disable_config('DVB_FE_CUSTOMISE'); # Hack for check sound/oss/aci.h header my $mirodep="$kernel/sound/oss/aci.h"; -if (!open IN, $mirodep) { +if (! -e $mirodep) { my $key="RADIO_MIROPCM20"; -print <<"EOF2"; + print <<"EOF2"; $key: $mirodep is missing. ***WARNING:*** You do not have the full kernel sources installed. @@ -431,7 +428,6 @@ Please see your distro's web site for instructions to build a new kernel. EOF2 $kernopts{$key}='n'; } -close IN; # Recursively check for broken dependencies my $i; diff --git a/v4l/scripts/rmmod.pl b/v4l/scripts/rmmod.pl index 19a0a8c61..ade231707 100755 --- a/v4l/scripts/rmmod.pl +++ b/v4l/scripts/rmmod.pl @@ -173,22 +173,22 @@ if ($mode eq "load") { prepare_cmd; parse_loaded; rmmod; + } elsif ($mode eq "reload") { + prepare_cmd; + parse_loaded; + my @modlist2=@modlist; + rmmod; + @modlist=@modlist2; + insmod(0); + } elsif ($mode eq "debug") { + prepare_cmd; + parse_loaded; + insmod(1); + } elsif ($mode eq "check") { + prepare_cmd; + parse_loaded; } else { - if ($mode eq "reload") { - prepare_cmd; - parse_loaded; - my @modlist2=@modlist; - rmmod; - @modlist=@modlist2; - insmod(0); - } else { - if ($mode eq "debug") { - prepare_cmd; - parse_loaded; - insmod(1); - } else { - printf "Usage: $0 [load|unload|reload]\n"; - } - } + printf "Usage: $0 [load|unload|reload|debug|check]\n"; } } + |