summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--linux/Documentation/video4linux/CARDLIST.saa71341
-rw-r--r--linux/drivers/media/dvb/dvb-core/Makefile6
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig83
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile2
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.c740
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.h41
-rw-r--r--linux/drivers/media/dvb/frontends/tda826x.c173
-rw-r--r--linux/drivers/media/dvb/frontends/tda826x.h40
-rw-r--r--linux/drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c3
-rw-r--r--linux/drivers/media/dvb/ttpci/budget.c29
-rw-r--r--linux/drivers/media/dvb/ttusb-budget/Kconfig2
-rw-r--r--linux/drivers/media/radio/Kconfig14
-rw-r--r--linux/drivers/media/radio/Makefile1
-rw-r--r--linux/drivers/media/radio/dsbr100.c (renamed from linux/drivers/media/video/dsbr100.c)198
-rw-r--r--linux/drivers/media/radio/radio-cadet.c244
-rw-r--r--linux/drivers/media/video/Kconfig12
-rw-r--r--linux/drivers/media/video/Makefile1
-rw-r--r--linux/drivers/media/video/compat_ioctl32.c32
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c4
-rw-r--r--linux/drivers/media/video/pwc/Kconfig2
-rw-r--r--linux/drivers/media/video/saa7134/Kconfig3
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c38
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c19
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-video.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h1
-rw-r--r--linux/drivers/media/video/usbvideo/konicawc.c9
-rw-r--r--linux/drivers/media/video/v4l2-common.c6
-rw-r--r--linux/drivers/media/video/videodev.c2
-rw-r--r--linux/drivers/media/video/vivi.c4
-rw-r--r--v4l/Makefile2
-rwxr-xr-xv4l/scripts/make_kconfig.pl16
-rwxr-xr-xv4l/scripts/rmmod.pl32
34 files changed, 1501 insertions, 274 deletions
diff --git a/Makefile b/Makefile
index 9d6f7c3e7..f0101af9a 100644
--- a/Makefile
+++ b/Makefile
@@ -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";
}
}
+