diff options
Diffstat (limited to 'drivers/media/dvb')
130 files changed, 2584 insertions, 1174 deletions
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index ee214c3..f6e40b3 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig @@ -80,6 +80,10 @@ comment "Supported nGene Adapters" depends on DVB_CORE && PCI && I2C source "drivers/media/dvb/ngene/Kconfig" +comment "Supported ddbridge ('Octopus') Adapters" + depends on DVB_CORE && PCI && I2C + source "drivers/media/dvb/ddbridge/Kconfig" + comment "Supported DVB Frontends" depends on DVB_CORE source "drivers/media/dvb/frontends/Kconfig" diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile index a1a0875..b2cefe6 100644 --- a/drivers/media/dvb/Makefile +++ b/drivers/media/dvb/Makefile @@ -15,6 +15,7 @@ obj-y := dvb-core/ \ dm1105/ \ pt1/ \ mantis/ \ - ngene/ + ngene/ \ + ddbridge/ obj-$(CONFIG_DVB_FIREDTV) += firewire/ diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile index b97cf72..3d04a8d 100644 --- a/drivers/media/dvb/b2c2/Makefile +++ b/drivers/media/dvb/b2c2/Makefile @@ -12,5 +12,5 @@ obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o b2c2-flexcop-usb-objs = flexcop-usb.o obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ -EXTRA_CFLAGS += -Idrivers/media/common/tuners/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ +ccflags-y += -Idrivers/media/common/tuners/ diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h index 9e2148a..437912e 100644 --- a/drivers/media/dvb/b2c2/flexcop-common.h +++ b/drivers/media/dvb/b2c2/flexcop-common.h @@ -6,6 +6,7 @@ #ifndef __FLEXCOP_COMMON_H__ #define __FLEXCOP_COMMON_H__ +#include <linux/interrupt.h> #include <linux/pci.h> #include <linux/mutex.h> diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile index d98f1d4..0713b3a 100644 --- a/drivers/media/dvb/bt8xx/Makefile +++ b/drivers/media/dvb/bt8xx/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -EXTRA_CFLAGS += -Idrivers/media/video/bt8xx -EXTRA_CFLAGS += -Idrivers/media/common/tuners +ccflags-y += -Idrivers/media/dvb/dvb-core +ccflags-y += -Idrivers/media/dvb/frontends +ccflags-y += -Idrivers/media/video/bt8xx +ccflags-y += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index 1e1106d..521d691 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c @@ -892,7 +892,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) { printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr); kfree(card); - return -EFAULT; + return -ENODEV; } if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) { @@ -902,7 +902,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub) "installed, try removing it.\n"); kfree(card); - return -EFAULT; + return -ENODEV; } mutex_init(&card->bt->gpio_lock); diff --git a/drivers/media/dvb/dm1105/Makefile b/drivers/media/dvb/dm1105/Makefile index 8ac28b0..95a008b 100644 --- a/drivers/media/dvb/dm1105/Makefile +++ b/drivers/media/dvb/dm1105/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_DVB_DM1105) += dm1105.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c index b2b0c45..55e6533 100644 --- a/drivers/media/dvb/dm1105/dm1105.c +++ b/drivers/media/dvb/dm1105/dm1105.c @@ -22,6 +22,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> diff --git a/drivers/media/dvb/dvb-core/Makefile b/drivers/media/dvb/dvb-core/Makefile index 0b51828..8f22bcd 100644 --- a/drivers/media/dvb/dvb-core/Makefile +++ b/drivers/media/dvb/dvb-core/Makefile @@ -2,8 +2,10 @@ # Makefile for the kernel DVB device drivers. # +dvb-net-$(CONFIG_DVB_NET) := dvb_net.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 + $(dvb-net-y) dvb_ringbuffer.o dvb_math.o obj-$(CONFIG_DVB_CORE) += dvb-core.o diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index e4b5c03..4f8c3f7 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c @@ -380,10 +380,8 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, ret = dvb_dmxdev_buffer_write(&dmxdevfilter->buffer, buffer2, buffer2_len); } - if (ret < 0) { - dvb_ringbuffer_flush(&dmxdevfilter->buffer); + if (ret < 0) dmxdevfilter->buffer.error = ret; - } if (dmxdevfilter->params.sec.flags & DMX_ONESHOT) dmxdevfilter->state = DMXDEV_STATE_DONE; spin_unlock(&dmxdevfilter->dev->lock); @@ -419,10 +417,8 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, ret = dvb_dmxdev_buffer_write(buffer, buffer1, buffer1_len); if (ret == buffer1_len) ret = dvb_dmxdev_buffer_write(buffer, buffer2, buffer2_len); - if (ret < 0) { - dvb_ringbuffer_flush(buffer); + if (ret < 0) buffer->error = ret; - } spin_unlock(&dmxdevfilter->dev->lock); wake_up(&buffer->queue); return 0; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 5b6b451..2c0acdb 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -149,30 +149,25 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) dprintk ("%s\n", __func__); - if (mutex_lock_interruptible (&events->mtx)) - return; + if ((status & FE_HAS_LOCK) && fe->ops.get_frontend) + fe->ops.get_frontend(fe, &fepriv->parameters_out); - wp = (events->eventw + 1) % MAX_EVENT; + mutex_lock(&events->mtx); + wp = (events->eventw + 1) % MAX_EVENT; if (wp == events->eventr) { events->overflow = 1; events->eventr = (events->eventr + 1) % MAX_EVENT; } e = &events->events[events->eventw]; - - if (status & FE_HAS_LOCK) - if (fe->ops.get_frontend) - fe->ops.get_frontend(fe, &fepriv->parameters_out); - + e->status = status; e->parameters = fepriv->parameters_out; events->eventw = wp; mutex_unlock(&events->mtx); - e->status = status; - wake_up_interruptible (&events->wait_queue); } @@ -207,19 +202,24 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe, return ret; } - if (mutex_lock_interruptible (&events->mtx)) - return -ERESTARTSYS; - - memcpy (event, &events->events[events->eventr], - sizeof(struct dvb_frontend_event)); - + mutex_lock(&events->mtx); + *event = events->events[events->eventr]; events->eventr = (events->eventr + 1) % MAX_EVENT; - mutex_unlock(&events->mtx); return 0; } +static void dvb_frontend_clear_events(struct dvb_frontend *fe) +{ + struct dvb_frontend_private *fepriv = fe->frontend_priv; + struct dvb_fe_events *events = &fepriv->events; + + mutex_lock(&events->mtx); + events->eventr = events->eventw; + mutex_unlock(&events->mtx); +} + static void dvb_frontend_init(struct dvb_frontend *fe) { dprintk ("DVB: initialising adapter %i frontend %i (%s)...\n", @@ -537,7 +537,6 @@ static int dvb_frontend_thread(void *data) { struct dvb_frontend *fe = data; struct dvb_frontend_private *fepriv = fe->frontend_priv; - unsigned long timeout; fe_status_t s; enum dvbfe_algo algo; @@ -558,7 +557,7 @@ static int dvb_frontend_thread(void *data) while (1) { up(&fepriv->sem); /* is locked when we enter the thread... */ restart: - timeout = wait_event_interruptible_timeout(fepriv->wait_queue, + wait_event_interruptible_timeout(fepriv->wait_queue, dvb_frontend_should_wakeup(fe) || kthread_should_stop() || freezing(current), fepriv->delay); @@ -577,12 +576,10 @@ restart: if (fepriv->reinitialise) { dvb_frontend_init(fe); - if (fepriv->tone != -1) { + if (fe->ops.set_tone && fepriv->tone != -1) fe->ops.set_tone(fe, fepriv->tone); - } - if (fepriv->voltage != -1) { + if (fe->ops.set_voltage && fepriv->voltage != -1) fe->ops.set_voltage(fe, fepriv->voltage); - } fepriv->reinitialise = 0; } @@ -904,7 +901,7 @@ static int dvb_frontend_clear_cache(struct dvb_frontend *fe) .buffer = b \ } -static struct dtv_cmds_h dtv_cmds[] = { +static struct dtv_cmds_h dtv_cmds[DTV_MAX_COMMAND + 1] = { _DTV_CMD(DTV_TUNE, 1, 0), _DTV_CMD(DTV_CLEAR, 1, 0), @@ -966,6 +963,7 @@ static struct dtv_cmds_h dtv_cmds[] = { _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0), _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0), + _DTV_CMD(DTV_DVBT2_PLP_ID, 1, 0), /* Get */ _DTV_CMD(DTV_DISEQC_SLAVE_REPLY, 0, 1), @@ -1018,6 +1016,29 @@ static int is_legacy_delivery_system(fe_delivery_system_t s) return 0; } +/* Initialize the cache with some default values derived from the + * legacy frontend_info structure. + */ +static void dtv_property_cache_init(struct dvb_frontend *fe, + struct dtv_frontend_properties *c) +{ + switch (fe->ops.info.type) { + case FE_QPSK: + c->modulation = QPSK; /* implied for DVB-S in legacy API */ + c->rolloff = ROLLOFF_35;/* implied for DVB-S */ + c->delivery_system = SYS_DVBS; + break; + case FE_QAM: + c->delivery_system = SYS_DVBC_ANNEX_AC; + break; + case FE_OFDM: + c->delivery_system = SYS_DVBT; + break; + case FE_ATSC: + break; + } +} + /* Synchronise the legacy tuning parameters into the cache, so that demodulator * drivers can use a single set_frontend tuning function, regardless of whether * it's being used for the legacy or new API, reducing code and complexity. @@ -1031,17 +1052,13 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe, switch (fe->ops.info.type) { case FE_QPSK: - c->modulation = QPSK; /* implied for DVB-S in legacy API */ - c->rolloff = ROLLOFF_35;/* implied for DVB-S */ c->symbol_rate = p->u.qpsk.symbol_rate; c->fec_inner = p->u.qpsk.fec_inner; - c->delivery_system = SYS_DVBS; break; case FE_QAM: c->symbol_rate = p->u.qam.symbol_rate; c->fec_inner = p->u.qam.fec_inner; c->modulation = p->u.qam.modulation; - c->delivery_system = SYS_DVBC_ANNEX_AC; break; case FE_OFDM: if (p->u.ofdm.bandwidth == BANDWIDTH_6_MHZ) @@ -1059,7 +1076,6 @@ static void dtv_property_cache_sync(struct dvb_frontend *fe, c->transmission_mode = p->u.ofdm.transmission_mode; c->guard_interval = p->u.ofdm.guard_interval; c->hierarchy = p->u.ofdm.hierarchy_information; - c->delivery_system = SYS_DVBT; break; case FE_ATSC: c->modulation = p->u.vsb.modulation; @@ -1131,16 +1147,13 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe) p->frequency = c->frequency; p->inversion = c->inversion; - switch(c->modulation) { - case PSK_8: - case APSK_16: - case APSK_32: - case QPSK: + if (c->delivery_system == SYS_DSS || + c->delivery_system == SYS_DVBS || + c->delivery_system == SYS_DVBS2 || + c->delivery_system == SYS_ISDBS || + c->delivery_system == SYS_TURBO) { p->u.qpsk.symbol_rate = c->symbol_rate; p->u.qpsk.fec_inner = c->fec_inner; - break; - default: - break; } /* Fake out a generic DVB-T request so we pass validation in the ioctl */ @@ -1823,9 +1836,17 @@ static int dvb_frontend_ioctl_legacy(struct file *file, memcpy (&fepriv->parameters_in, parg, sizeof (struct dvb_frontend_parameters)); + dtv_property_cache_init(fe, c); dtv_property_cache_sync(fe, c, &fepriv->parameters_in); } + /* + * Initialize output parameters to match the values given by + * the user. FE_SET_FRONTEND triggers an initial frontend event + * with status = 0, which copies output parameters to userspace. + */ + fepriv->parameters_out = fepriv->parameters_in; + memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings)); memcpy(&fetunesettings.parameters, parg, sizeof (struct dvb_frontend_parameters)); @@ -1883,8 +1904,9 @@ static int dvb_frontend_ioctl_legacy(struct file *file, /* Request the search algorithm to search */ fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN; - dvb_frontend_wakeup(fe); + dvb_frontend_clear_events(fe); dvb_frontend_add_event(fe, 0); + dvb_frontend_wakeup(fe); fepriv->status = 0; err = 0; break; diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h index 5590eb6..67bbfa7 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.h +++ b/drivers/media/dvb/dvb-core/dvb_frontend.h @@ -209,6 +209,7 @@ struct dvb_tuner_ops { int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency); int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth); + int (*get_if_frequency)(struct dvb_frontend *fe, u32 *frequency); #define TUNER_STATUS_LOCKED 1 #define TUNER_STATUS_STEREO 2 diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 51752a9..93d9869 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -1230,7 +1230,7 @@ static const struct net_device_ops dvb_netdev_ops = { .ndo_open = dvb_net_open, .ndo_stop = dvb_net_stop, .ndo_start_xmit = dvb_net_tx, - .ndo_set_multicast_list = dvb_net_set_multicast_list, + .ndo_set_rx_mode = dvb_net_set_multicast_list, .ndo_set_mac_address = dvb_net_set_mac, .ndo_change_mtu = eth_change_mtu, .ndo_validate_addr = eth_validate_addr, diff --git a/drivers/media/dvb/dvb-core/dvb_net.h b/drivers/media/dvb/dvb-core/dvb_net.h index 3a3126ca..1e53acd 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.h +++ b/drivers/media/dvb/dvb-core/dvb_net.h @@ -32,6 +32,8 @@ #define DVB_NET_DEVICES_MAX 10 +#ifdef CONFIG_DVB_NET + struct dvb_net { struct dvb_device *dvbdev; struct net_device *device[DVB_NET_DEVICES_MAX]; @@ -40,8 +42,25 @@ struct dvb_net { struct dmx_demux *demux; }; - void dvb_net_release(struct dvb_net *); int dvb_net_init(struct dvb_adapter *, struct dvb_net *, struct dmx_demux *); +#else + +struct dvb_net { + struct dvb_device *dvbdev; +}; + +static inline void dvb_net_release(struct dvb_net *dvbnet) +{ +} + +static inline int dvb_net_init(struct dvb_adapter *adap, + struct dvb_net *dvbnet, struct dmx_demux *dmx) +{ + return 0; +} + +#endif /* ifdef CONFIG_DVB_NET */ + #endif diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index e85304c..5825716 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -81,6 +81,7 @@ config DVB_USB_DIB0700 select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE + select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE help Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The @@ -257,6 +258,19 @@ config DVB_USB_AF9005_REMOTE Say Y here to support the default remote control decoding for the Afatech AF9005 based receiver. +config DVB_USB_PCTV452E + tristate "Pinnacle PCTV HDTV Pro USB device/TT Connect S2-3600" + depends on DVB_USB + select TTPCI_EEPROM + select DVB_LNBP22 if !DVB_FE_CUSTOMISE + select DVB_STB0899 if !DVB_FE_CUSTOMISE + select DVB_STB6100 if !DVB_FE_CUSTOMISE + help + Support for external USB adapter designed by Pinnacle, + shipped under the brand name 'PCTV HDTV Pro USB'. + Also supports TT Connect S2-3600/3650 cards. + Say Y if you own such a device and want to use it. + config DVB_USB_DW2102 tristate "DvbWorld & TeVii DVB-S/S2 USB2.0 support" depends on DVB_USB @@ -373,3 +387,18 @@ config DVB_USB_TECHNISAT_USB2 select DVB_STV6110x if !DVB_FE_CUSTOMISE help Say Y here to support the Technisat USB2 DVB-S/S2 device + +config DVB_USB_IT913X + tristate "it913x driver" + depends on DVB_USB + select DVB_IT913X_FE + help + Say Y here to support the it913x device + +config DVB_USB_MXL111SF + tristate "MxL111SF DTV USB2.0 support" + depends on DVB_USB + select DVB_LGDT3305 if !DVB_FE_CUSTOMISE + select VIDEO_TVEEPROM + help + Say Y here to support the MxL111SF USB2.0 DTV receiver. diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 4bac13d..26c8b9e 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -64,6 +64,9 @@ obj-$(CONFIG_DVB_USB_AF9005_REMOTE) += dvb-usb-af9005-remote.o dvb-usb-anysee-objs = anysee.o obj-$(CONFIG_DVB_USB_ANYSEE) += dvb-usb-anysee.o +dvb-usb-pctv452e-objs = pctv452e.o +obj-$(CONFIG_DVB_USB_PCTV452E) += dvb-usb-pctv452e.o + dvb-usb-dw2102-objs = dw2102.o obj-$(CONFIG_DVB_USB_DW2102) += dvb-usb-dw2102.o @@ -94,7 +97,16 @@ obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o dvb-usb-technisat-usb2-objs = technisat-usb2.o obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ +dvb-usb-it913x-objs := it913x.o +obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o + +dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o +obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o +obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o +obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o + +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ # due to tuner-xc3028 -EXTRA_CFLAGS += -Idrivers/media/common/tuners +ccflags-y += -Idrivers/media/common/tuners +EXTRA_CFLAGS += -Idrivers/media/dvb/ttpci diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index b95a95e..2aef3c8 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -127,6 +127,8 @@ static struct dvb_usb_device_properties a800_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .streaming_ctrl = dibusb2_0_streaming_ctrl, @@ -147,7 +149,7 @@ static struct dvb_usb_device_properties a800_properties = { } } }, - + }}, .size_of_priv = sizeof(struct dibusb_state), }, }, diff --git a/drivers/media/dvb/dvb-usb/af9005-fe.c b/drivers/media/dvb/dvb-usb/af9005-fe.c index 6ad9474..3263e97 100644 --- a/drivers/media/dvb/dvb-usb/af9005-fe.c +++ b/drivers/media/dvb/dvb-usb/af9005-fe.c @@ -63,11 +63,9 @@ static int af9005_write_word_agc(struct dvb_usb_device *d, u16 reghi, u16 reglo, u8 pos, u8 len, u16 value) { int ret; - u8 temp; if ((ret = af9005_write_ofdm_register(d, reglo, (u8) (value & 0xff)))) return ret; - temp = (u8) ((value & 0x0300) >> 8); return af9005_write_register_bits(d, reghi, pos, len, (u8) ((value & 0x300) >> 8)); } diff --git a/drivers/media/dvb/dvb-usb/af9005-remote.c b/drivers/media/dvb/dvb-usb/af9005-remote.c index c3bc64e..7e3961d 100644 --- a/drivers/media/dvb/dvb-usb/af9005-remote.c +++ b/drivers/media/dvb/dvb-usb/af9005-remote.c @@ -21,7 +21,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * see Documentation/dvb/REDME.dvb-usb for more information + * see Documentation/dvb/README.dvb-usb for more information */ #include "af9005.h" /* debug */ diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c index 51f6439..0b3ef9f 100644 --- a/drivers/media/dvb/dvb-usb/af9005.c +++ b/drivers/media/dvb/dvb-usb/af9005.c @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * see Documentation/dvb/REDME.dvb-usb for more information + * see Documentation/dvb/README.dvb-usb for more information */ #include "af9005.h" @@ -815,7 +815,7 @@ static int af9005_frontend_attach(struct dvb_usb_adapter *adap) debug_dump(buf, 8, printk); } } - adap->fe = af9005_fe_attach(adap->dev); + adap->fe_adap[0].fe = af9005_fe_attach(adap->dev); return 0; } @@ -999,6 +999,8 @@ static struct dvb_usb_device_properties af9005_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1018,6 +1020,7 @@ static struct dvb_usb_device_properties af9005_properties = { } } }, + }}, } }, .power_ctrl = af9005_power_ctrl, @@ -1069,9 +1072,12 @@ static int __init af9005_usb_module_init(void) err("usb_register failed. (%d)", result); return result; } +#if IS_MODULE(CONFIG_DVB_USB_AF9005) || defined(CONFIG_DVB_USB_AF9005_REMOTE) + /* FIXME: convert to todays kernel IR infrastructure */ rc_decode = symbol_request(af9005_rc_decode); rc_keys = symbol_request(rc_map_af9005_table); rc_keys_size = symbol_request(rc_map_af9005_table_size); +#endif if (rc_decode == NULL || rc_keys == NULL || rc_keys_size == NULL) { err("af9005_rc_decode function not found, disabling remote"); af9005_properties.rc.legacy.rc_query = NULL; diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 100ebc3..c6c275b 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -91,7 +91,6 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) case GET_CONFIG: case READ_MEMORY: case RECONNECT_USB: - case GET_IR_CODE: write = 0; break; case READ_I2C: @@ -164,13 +163,6 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) deb_xfer("<<< "); debug_dump(buf, act_len, deb_xfer); - /* remote controller query status is 1 if remote code is not received */ - if (req->cmd == GET_IR_CODE && buf[1] == 1) { - buf[1] = 0; /* clear command "error" status */ - memset(&buf[2], 0, req->data_len); - buf[3] = 1; /* no remote code received mark */ - } - /* check status */ if (buf[1]) { err("command failed:%d", buf[1]); @@ -292,6 +284,10 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. } if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) { + if (msg[i].len > 3 || msg[i+1].len > 61) { + ret = -EOPNOTSUPP; + goto error; + } if (msg[i].addr == af9015_af9013_config[0].demod_address) req.cmd = READ_MEMORY; @@ -306,12 +302,16 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = af9015_ctrl_msg(d, &req); i += 2; } else if (msg[i].flags & I2C_M_RD) { - ret = -EINVAL; + if (msg[i].len > 61) { + ret = -EOPNOTSUPP; + goto error; + } if (msg[i].addr == - af9015_af9013_config[0].demod_address) + af9015_af9013_config[0].demod_address) { + ret = -EINVAL; goto error; - else - req.cmd = READ_I2C; + } + req.cmd = READ_I2C; req.i2c_addr = msg[i].addr; req.addr = addr; req.mbox = mbox; @@ -321,6 +321,10 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate. ret = af9015_ctrl_msg(d, &req); i += 1; } else { + if (msg[i].len > 21) { + ret = -EOPNOTSUPP; + goto error; + } if (msg[i].addr == af9015_af9013_config[0].demod_address) req.cmd = WRITE_MEMORY; @@ -735,30 +739,37 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = { { 0xb8feb708, RC_MAP_MSI_DIGIVOX_II }, { 0xa3703d00, RC_MAP_ALINK_DTU_M }, { 0x9b7dc64e, RC_MAP_TOTAL_MEDIA_IN_HAND }, /* MYGICTV U718 */ + { 0x5d49e3db, RC_MAP_DIGITTRADE }, /* LC-Power LC-USB-DVBT */ { } }; static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { - { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC, + { (USB_VID_TERRATEC << 16) | USB_PID_TERRATEC_CINERGY_T_STICK_RC, RC_MAP_TERRATEC_SLIM_2 }, - { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, + { (USB_VID_TERRATEC << 16) | USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, RC_MAP_TERRATEC_SLIM }, - { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, + { (USB_VID_VISIONPLUS << 16) | USB_PID_AZUREWAVE_AD_TU700, RC_MAP_AZUREWAVE_AD_TU700 }, - { (USB_VID_VISIONPLUS << 16) + USB_PID_TINYTWIN, + { (USB_VID_VISIONPLUS << 16) | USB_PID_TINYTWIN, RC_MAP_AZUREWAVE_AD_TU700 }, - { (USB_VID_MSI_2 << 16) + USB_PID_MSI_DIGI_VOX_MINI_III, + { (USB_VID_MSI_2 << 16) | USB_PID_MSI_DIGI_VOX_MINI_III, RC_MAP_MSI_DIGIVOX_III }, - { (USB_VID_LEADTEK << 16) + USB_PID_WINFAST_DTV_DONGLE_GOLD, + { (USB_VID_MSI_2 << 16) | USB_PID_MSI_DIGIVOX_DUO, + RC_MAP_MSI_DIGIVOX_III }, + { (USB_VID_LEADTEK << 16) | USB_PID_WINFAST_DTV_DONGLE_GOLD, + RC_MAP_LEADTEK_Y04G0051 }, + { (USB_VID_LEADTEK << 16) | USB_PID_WINFAST_DTV2000DS, RC_MAP_LEADTEK_Y04G0051 }, - { (USB_VID_AVERMEDIA << 16) + USB_PID_AVERMEDIA_VOLAR_X, + { (USB_VID_AVERMEDIA << 16) | USB_PID_AVERMEDIA_VOLAR_X, RC_MAP_AVERMEDIA_M135A }, - { (USB_VID_AFATECH << 16) + USB_PID_TREKSTOR_DVBT, + { (USB_VID_AFATECH << 16) | USB_PID_TREKSTOR_DVBT, RC_MAP_TREKSTOR }, - { (USB_VID_KWORLD_2 << 16) + USB_PID_TINYTWIN_2, + { (USB_VID_KWORLD_2 << 16) | USB_PID_TINYTWIN_2, RC_MAP_DIGITALNOW_TINYTWIN }, - { (USB_VID_GTEK << 16) + USB_PID_TINYTWIN_3, + { (USB_VID_GTEK << 16) | USB_PID_TINYTWIN_3, RC_MAP_DIGITALNOW_TINYTWIN }, + { (USB_VID_KWORLD_2 << 16) | USB_PID_SVEON_STV22, + RC_MAP_MSI_DIGIVOX_III }, { } }; @@ -850,13 +861,13 @@ static int af9015_read_config(struct usb_device *udev) for (i = 0; i < af9015_properties_count; i++) { /* USB1.1 set smaller buffersize and disable 2nd adapter */ if (udev->speed == USB_SPEED_FULL) { - af9015_properties[i].adapter[0].stream.u.bulk.buffersize + af9015_properties[i].adapter[0].fe[0].stream.u.bulk.buffersize = TS_USB11_FRAME_SIZE; /* disable 2nd adapter because we don't have PID-filters */ af9015_config.dual_mode = 0; } else { - af9015_properties[i].adapter[0].stream.u.bulk.buffersize + af9015_properties[i].adapter[0].fe[0].stream.u.bulk.buffersize = TS_USB20_FRAME_SIZE; } } @@ -1082,44 +1093,11 @@ error: return ret; } -/* init 2nd I2C adapter */ -static int af9015_i2c_init(struct dvb_usb_device *d) -{ - int ret; - struct af9015_state *state = d->priv; - deb_info("%s:\n", __func__); - - strncpy(state->i2c_adap.name, d->desc->name, - sizeof(state->i2c_adap.name)); - state->i2c_adap.algo = d->props.i2c_algo; - state->i2c_adap.algo_data = NULL; - state->i2c_adap.dev.parent = &d->udev->dev; - - i2c_set_adapdata(&state->i2c_adap, d); - - ret = i2c_add_adapter(&state->i2c_adap); - if (ret < 0) - err("could not add i2c adapter"); - - return ret; -} - static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { int ret; - struct af9015_state *state = adap->dev->priv; - struct i2c_adapter *i2c_adap; - - if (adap->id == 0) { - /* select I2C adapter */ - i2c_adap = &adap->dev->i2c_adap; - - deb_info("%s: init I2C\n", __func__); - ret = af9015_i2c_init(adap->dev); - } else { - /* select I2C adapter */ - i2c_adap = &state->i2c_adap; + if (adap->id == 1) { /* copy firmware to 2nd demodulator */ if (af9015_config.dual_mode) { ret = af9015_copy_firmware(adap->dev); @@ -1135,10 +1113,10 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) } /* attach demodulator */ - adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], - i2c_adap); + adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id], + &adap->dev->i2c_adap); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static struct mt2060_config af9015_mt2060_config = { @@ -1206,57 +1184,56 @@ static struct mxl5007t_config af9015_mxl5007t_config = { static int af9015_tuner_attach(struct dvb_usb_adapter *adap) { - struct af9015_state *state = adap->dev->priv; - struct i2c_adapter *i2c_adap; int ret; deb_info("%s:\n", __func__); - /* select I2C adapter */ - if (adap->id == 0) - i2c_adap = &adap->dev->i2c_adap; - else - i2c_adap = &state->i2c_adap; - switch (af9015_af9013_config[adap->id].tuner) { case AF9013_TUNER_MT2060: case AF9013_TUNER_MT2060_2: - ret = dvb_attach(mt2060_attach, adap->fe, i2c_adap, + ret = dvb_attach(mt2060_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &af9015_mt2060_config, af9015_config.mt2060_if1[adap->id]) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_QT1010: case AF9013_TUNER_QT1010A: - ret = dvb_attach(qt1010_attach, adap->fe, i2c_adap, + ret = dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &af9015_qt1010_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_TDA18271: - ret = dvb_attach(tda18271_attach, adap->fe, 0xc0, i2c_adap, + ret = dvb_attach(tda18271_attach, adap->fe_adap[0].fe, 0xc0, + &adap->dev->i2c_adap, &af9015_tda18271_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_TDA18218: - ret = dvb_attach(tda18218_attach, adap->fe, i2c_adap, + ret = dvb_attach(tda18218_attach, adap->fe_adap[0].fe, + &adap->dev->i2c_adap, &af9015_tda18218_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MXL5003D: - ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, + ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, + &adap->dev->i2c_adap, &af9015_mxl5003_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MXL5005D: case AF9013_TUNER_MXL5005R: - ret = dvb_attach(mxl5005s_attach, adap->fe, i2c_adap, + ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, + &adap->dev->i2c_adap, &af9015_mxl5005_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_ENV77H11D5: - ret = dvb_attach(dvb_pll_attach, adap->fe, 0xc0, i2c_adap, + ret = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0xc0, + &adap->dev->i2c_adap, DVB_PLL_TDA665X) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MC44S803: - ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap, + ret = dvb_attach(mc44s803_attach, adap->fe_adap[0].fe, + &adap->dev->i2c_adap, &af9015_mc44s803_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_MXL5007T: - ret = dvb_attach(mxl5007t_attach, adap->fe, i2c_adap, + ret = dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe, + &adap->dev->i2c_adap, 0xc0, &af9015_mxl5007t_config) == NULL ? -ENODEV : 0; break; case AF9013_TUNER_UNKNOWN: @@ -1309,6 +1286,7 @@ static struct usb_device_id af9015_usb_table[] = { USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC)}, /* 35 */{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A850T)}, {USB_DEVICE(USB_VID_GTEK, USB_PID_TINYTWIN_3)}, + {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_SVEON_STV22)}, {0}, }; MODULE_DEVICE_TABLE(usb, af9015_usb_table); @@ -1328,6 +1306,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1343,8 +1323,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .count = 6, .endpoint = 0x84, }, + }}, }, { + .num_frontends = 1, + .fe = {{ .frontend_attach = af9015_af9013_frontend_attach, .tuner_attach = af9015_tuner_attach, @@ -1359,6 +1342,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { } } }, + }}, } }, @@ -1456,6 +1440,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1471,8 +1457,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .count = 6, .endpoint = 0x84, }, + }}, }, { + .num_frontends = 1, + .fe = {{ .frontend_attach = af9015_af9013_frontend_attach, .tuner_attach = af9015_tuner_attach, @@ -1487,6 +1476,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { } } }, + }}, } }, @@ -1502,7 +1492,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { .i2c_algo = &af9015_i2c_algo, - .num_device_descs = 9, /* check max from dvb-usb.h */ + .num_device_descs = 10, /* check max from dvb-usb.h */ .devices = { { .name = "Xtensions XD-380", @@ -1554,6 +1544,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .cold_ids = {&af9015_usb_table[20], NULL}, .warm_ids = {NULL}, }, + { + .name = "Sveon STV22 Dual USB DVB-T Tuner HDTV", + .cold_ids = {&af9015_usb_table[37], NULL}, + .warm_ids = {NULL}, + }, } }, { .caps = DVB_USB_IS_AN_I2C_ADAPTER, @@ -1568,6 +1563,8 @@ static struct dvb_usb_device_properties af9015_properties[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1583,8 +1580,11 @@ static struct dvb_usb_device_properties af9015_properties[] = { .count = 6, .endpoint = 0x84, }, + }}, }, { + .num_frontends = 1, + .fe = {{ .frontend_attach = af9015_af9013_frontend_attach, .tuner_attach = af9015_tuner_attach, @@ -1599,6 +1599,7 @@ static struct dvb_usb_device_properties af9015_properties[] = { } } }, + }}, } }, @@ -1704,33 +1705,11 @@ static int af9015_usb_probe(struct usb_interface *intf, return ret; } -static void af9015_i2c_exit(struct dvb_usb_device *d) -{ - struct af9015_state *state = d->priv; - deb_info("%s:\n", __func__); - - /* remove 2nd I2C adapter */ - if (d->state & DVB_USB_STATE_I2C) - i2c_del_adapter(&state->i2c_adap); -} - -static void af9015_usb_device_exit(struct usb_interface *intf) -{ - struct dvb_usb_device *d = usb_get_intfdata(intf); - deb_info("%s:\n", __func__); - - /* remove 2nd I2C adapter */ - if (d != NULL && d->desc != NULL) - af9015_i2c_exit(d); - - dvb_usb_device_exit(intf); -} - /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver af9015_usb_driver = { .name = "dvb_usb_af9015", .probe = af9015_usb_probe, - .disconnect = af9015_usb_device_exit, + .disconnect = dvb_usb_device_exit, .id_table = af9015_usb_table, }; diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index beb3004..6252ea6 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -99,7 +99,6 @@ enum af9015_ir_mode { }; struct af9015_state { - struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ u8 rc_repeat; u32 rc_keycode; u8 rc_last[4]; diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index 7c327b5..5f2278b 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -347,15 +347,17 @@ static struct isl6423_config anysee_isl6423_config = { * PCB: ? * parts: DNOS404ZH102A(MT352, DTT7579(?)) * - * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=???????? - * PCB: ? + * E30 VID=04b4 PID=861f HW=2 FW=2.1 "anysee-T(LP)" + * PCB: PCB 507T (rev1.61) * parts: DNOS404ZH103A(ZL10353, DTT7579(?)) + * OEA=0a OEB=00 OEC=00 OED=ff OEE=00 + * IOA=45 IOB=ff IOC=00 IOD=ff IOE=00 * * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee" * PCB: 507CD (rev1.1) * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01 - * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe - * IOA=4f IOB=ff IOC=00 IOD=06 IOF=01 + * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe + * IOA=4f IOB=ff IOC=00 IOD=06 IOE=01 * IOD[0] ZL10353 1=enabled * IOA[7] TS 0=enabled * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not) @@ -363,30 +365,30 @@ static struct isl6423_config anysee_isl6423_config = { * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)" * PCB: 507DC (rev0.2) * parts: TDA10023, DTOS403IH102B TM, CST56I01 - * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe - * IOA=4f IOB=ff IOC=00 IOD=26 IOF=01 + * OEA=80 OEB=00 OEC=00 OED=ff OEE=fe + * IOA=4f IOB=ff IOC=00 IOD=26 IOE=01 * IOD[0] TDA10023 1=enabled * * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)" * PCB: 507SI (rev2.1) * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024 - * OEA=80 OEB=00 OEC=ff OED=ff OEF=fe - * IOA=4d IOB=ff IOC=00 IOD=26 IOF=01 + * OEA=80 OEB=00 OEC=ff OED=ff OEE=fe + * IOA=4d IOB=ff IOC=00 IOD=26 IOE=01 * IOD[0] CX24116 1=enabled * * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)" * PCB: 507FA (rev0.4) * parts: TDA10023, DTOS403IH102B TM, TDA8024 - * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff - * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0 + * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff + * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0 * IOD[5] TDA10023 1=enabled * IOE[0] tuner 1=enabled * * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)" * PCB: 507FA (rev1.1) * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024 - * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff - * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0 + * OEA=80 OEB=00 OEC=ff OED=ff OEE=ff + * IOA=4d IOB=ff IOC=00 IOD=00 IOE=c0 * DVB-C: * IOD[5] TDA10023 1=enabled * IOE[0] tuner 1=enabled @@ -398,8 +400,8 @@ static struct isl6423_config anysee_isl6423_config = { * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)" * PCB: 508TC (rev0.6) * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) - * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff - * IOA=4d IOB=00 IOC=cc IOD=48 IOF=e4 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 * IOA[7] TS 1=enabled * IOE[4] TDA18212 1=enabled * DVB-C: @@ -414,13 +416,144 @@ static struct isl6423_config anysee_isl6423_config = { * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)" * PCB: 508S2 (rev0.7) * parts: DNBU10512IST(STV0903, STV6110), ISL6423 - * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff - * IOA=4d IOB=00 IOC=c4 IOD=08 IOF=e4 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4 * IOA[7] TS 1=enabled * IOE[5] STV0903 1=enabled * + * E7 PTC VID=1c73 PID=861f HW=21 FW=0.1 AMTCI=?? "anysee-E7PTC(LP)" + * PCB: 508PTC (rev0.5) + * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212) + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=cc IOD=48 IOE=e4 + * IOA[7] TS 1=enabled + * IOE[4] TDA18212 1=enabled + * DVB-C: + * IOD[6] ZL10353 0=disabled + * IOD[5] TDA10023 1=enabled + * IOE[0] IF 1=enabled + * DVB-T: + * IOD[5] TDA10023 0=disabled + * IOD[6] ZL10353 1=enabled + * IOE[0] IF 0=enabled + * + * E7 S2 VID=1c73 PID=861f HW=22 FW=0.1 AMTCI=?? "anysee-E7PS2(LP)" + * PCB: 508PS2 (rev0.4) + * parts: DNBU10512IST(STV0903, STV6110), ISL6423 + * OEA=80 OEB=00 OEC=03 OED=f7 OEE=ff + * IOA=4d IOB=00 IOC=c4 IOD=08 IOE=e4 + * IOA[7] TS 1=enabled + * IOE[5] STV0903 1=enabled */ +static int anysee_frontend_ctrl(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct anysee_state *state = adap->dev->priv; + int ret; + + deb_info("%s: fe=%d onoff=%d\n", __func__, fe->id, onoff); + + /* no frontend sleep control */ + if (onoff == 0) + return 0; + + switch (state->hw) { + case ANYSEE_HW_507FA: /* 15 */ + /* E30 Combo Plus */ + /* E30 C Plus */ + + if ((fe->id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), + 0x01); + if (ret) + goto error; + + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); + if (ret) + goto error; + + /* enable DVB-C tuner on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), + 0x01); + if (ret) + goto error; + } else { + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), + 0x20); + if (ret) + goto error; + + /* enable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), + 0x01); + if (ret) + goto error; + + /* enable DVB-T tuner on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), + 0x01); + if (ret) + goto error; + } + + break; + case ANYSEE_HW_508TC: /* 18 */ + case ANYSEE_HW_508PTC: /* 21 */ + /* E7 TC */ + /* E7 PTC */ + + if ((fe->id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), + 0x40); + if (ret) + goto error; + + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); + if (ret) + goto error; + + /* enable IF route on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), + 0x01); + if (ret) + goto error; + } else { + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), + 0x20); + if (ret) + goto error; + + /* enable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6), + 0x40); + if (ret) + goto error; + + /* enable IF route on IOE[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), + 0x01); + if (ret) + goto error; + } + + break; + default: + ret = 0; + } + +error: + return ret; +} + static int anysee_frontend_attach(struct dvb_usb_adapter *adap) { int ret; @@ -441,41 +574,54 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) } }; - /* Check which hardware we have. - * We must do this call two times to get reliable values (hw bug). - */ - ret = anysee_get_hw_info(adap->dev, hw_info); - if (ret) - goto error; + /* detect hardware only once */ + if (adap->fe_adap[0].fe == NULL) { + /* Check which hardware we have. + * We must do this call two times to get reliable values (hw bug). + */ + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) + goto error; - ret = anysee_get_hw_info(adap->dev, hw_info); - if (ret) - goto error; + ret = anysee_get_hw_info(adap->dev, hw_info); + if (ret) + goto error; - /* Meaning of these info bytes are guessed. */ - info("firmware version:%d.%d hardware id:%d", - hw_info[1], hw_info[2], hw_info[0]); + /* Meaning of these info bytes are guessed. */ + info("firmware version:%d.%d hardware id:%d", + hw_info[1], hw_info[2], hw_info[0]); - state->hw = hw_info[0]; + state->hw = hw_info[0]; + } + + /* set current frondend ID for devices having two frondends */ + if (adap->fe_adap[0].fe) + state->fe_id++; switch (state->hw) { - case ANYSEE_HW_02: /* 2 */ + case ANYSEE_HW_507T: /* 2 */ /* E30 */ + if (state->fe_id) + break; + /* attach demod */ - adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config, + adap->fe_adap[0].fe = dvb_attach(mt352_attach, &anysee_mt352_config, &adap->dev->i2c_adap); - if (adap->fe) + if (adap->fe_adap[0].fe) break; /* attach demod */ - adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507CD: /* 6 */ /* E30 Plus */ + if (state->fe_id) + break; + /* enable DVB-T demod on IOD[0] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); if (ret) @@ -487,33 +633,39 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, + &anysee_zl10353_config, &adap->dev->i2c_adap); break; case ANYSEE_HW_507DC: /* 10 */ /* E30 C Plus */ + if (state->fe_id) + break; + /* enable DVB-C demod on IOD[0] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); if (ret) goto error; /* attach demod */ - adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config, - &adap->dev->i2c_adap, 0x48); + adap->fe_adap[0].fe = dvb_attach(tda10023_attach, + &anysee_tda10023_config, &adap->dev->i2c_adap, 0x48); break; case ANYSEE_HW_507SI: /* 11 */ /* E30 S2 Plus */ + if (state->fe_id) + break; + /* enable DVB-S/S2 demod on IOD[0] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01); if (ret) goto error; /* attach demod */ - adap->fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, + adap->fe_adap[0].fe = dvb_attach(cx24116_attach, &anysee_cx24116_config, &adap->dev->i2c_adap); break; @@ -539,118 +691,117 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) if (ret) goto error; - if (dvb_usb_anysee_delsys) { - /* disable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), - 0x20); + if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), + 0x01); if (ret) goto error; - /* enable DVB-T demod on IOD[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), - 0x01); + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); if (ret) goto error; /* attach demod */ if (tmp == 0xc7) { /* TDA18212 config */ - adap->fe = dvb_attach(zl10353_attach, - &anysee_zl10353_tda18212_config2, - &adap->dev->i2c_adap); + adap->fe_adap[state->fe_id].fe = dvb_attach( + tda10023_attach, + &anysee_tda10023_tda18212_config, + &adap->dev->i2c_adap, 0x48); } else { /* PLL config */ - adap->fe = dvb_attach(zl10353_attach, - &anysee_zl10353_config, - &adap->dev->i2c_adap); + adap->fe_adap[state->fe_id].fe = dvb_attach( + tda10023_attach, + &anysee_tda10023_config, + &adap->dev->i2c_adap, 0x48); } } else { - /* disable DVB-T demod on IOD[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0), - 0x01); + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), + 0x20); if (ret) goto error; - /* enable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), - 0x20); + /* enable DVB-T demod on IOD[0] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), + 0x01); if (ret) goto error; /* attach demod */ if (tmp == 0xc7) { /* TDA18212 config */ - adap->fe = dvb_attach(tda10023_attach, - &anysee_tda10023_tda18212_config, - &adap->dev->i2c_adap, 0x48); + adap->fe_adap[state->fe_id].fe = dvb_attach( + zl10353_attach, + &anysee_zl10353_tda18212_config2, + &adap->dev->i2c_adap); } else { /* PLL config */ - adap->fe = dvb_attach(tda10023_attach, - &anysee_tda10023_config, - &adap->dev->i2c_adap, 0x48); + adap->fe_adap[state->fe_id].fe = dvb_attach( + zl10353_attach, + &anysee_zl10353_config, + &adap->dev->i2c_adap); } } break; case ANYSEE_HW_508TC: /* 18 */ + case ANYSEE_HW_508PTC: /* 21 */ /* E7 TC */ + /* E7 PTC */ /* enable transport stream on IOA[7] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); if (ret) goto error; - if (dvb_usb_anysee_delsys) { - /* disable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), - 0x20); - if (ret) - goto error; - - /* enable DVB-T demod on IOD[6] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6), + if ((state->fe_id ^ dvb_usb_anysee_delsys) == 0) { + /* disable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), 0x40); if (ret) goto error; - /* enable IF route on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), - 0x01); + /* enable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + 0x20); if (ret) goto error; /* attach demod */ - adap->fe = dvb_attach(zl10353_attach, - &anysee_zl10353_tda18212_config, - &adap->dev->i2c_adap); + adap->fe_adap[state->fe_id].fe = dvb_attach(tda10023_attach, + &anysee_tda10023_tda18212_config, + &adap->dev->i2c_adap, 0x48); } else { - /* disable DVB-T demod on IOD[6] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6), - 0x40); - if (ret) - goto error; - - /* enable DVB-C demod on IOD[5] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5), + /* disable DVB-C demod on IOD[5] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5), 0x20); if (ret) goto error; - /* enable IF route on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), - 0x01); + /* enable DVB-T demod on IOD[6] */ + ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6), + 0x40); if (ret) goto error; /* attach demod */ - adap->fe = dvb_attach(tda10023_attach, - &anysee_tda10023_tda18212_config, - &adap->dev->i2c_adap, 0x48); + adap->fe_adap[state->fe_id].fe = dvb_attach(zl10353_attach, + &anysee_zl10353_tda18212_config, + &adap->dev->i2c_adap); } break; case ANYSEE_HW_508S2: /* 19 */ + case ANYSEE_HW_508PS2: /* 22 */ /* E7 S2 */ + /* E7 PS2 */ + + if (state->fe_id) + break; /* enable transport stream on IOA[7] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80); @@ -663,13 +814,13 @@ static int anysee_frontend_attach(struct dvb_usb_adapter *adap) goto error; /* attach demod */ - adap->fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, + adap->fe_adap[0].fe = dvb_attach(stv0900_attach, &anysee_stv0900_config, &adap->dev->i2c_adap, 0); break; } - if (!adap->fe) { + if (!adap->fe_adap[0].fe) { /* we have no frontend :-( */ ret = -ENODEV; err("Unsupported Anysee version. " \ @@ -684,14 +835,14 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) struct anysee_state *state = adap->dev->priv; struct dvb_frontend *fe; int ret; - deb_info("%s:\n", __func__); + deb_info("%s: fe=%d\n", __func__, state->fe_id); switch (state->hw) { - case ANYSEE_HW_02: /* 2 */ + case ANYSEE_HW_507T: /* 2 */ /* E30 */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1), + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), NULL, DVB_PLL_THOMSON_DTT7579); break; @@ -699,7 +850,7 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1), + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc2 >> 1), &adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579); break; @@ -707,7 +858,7 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 C Plus */ /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1), + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, (0xc0 >> 1), &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); break; @@ -715,28 +866,14 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) /* E30 S2 Plus */ /* attach LNB controller */ - fe = dvb_attach(isl6423_attach, adap->fe, &adap->dev->i2c_adap, - &anysee_isl6423_config); + fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe, + &adap->dev->i2c_adap, &anysee_isl6423_config); break; case ANYSEE_HW_507FA: /* 15 */ /* E30 Combo Plus */ /* E30 C Plus */ - if (dvb_usb_anysee_delsys) { - /* enable DVB-T tuner on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0), - 0x01); - if (ret) - goto error; - } else { - /* enable DVB-C tuner on IOE[0] */ - ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0), - 0x01); - if (ret) - goto error; - } - /* Try first attach TDA18212 silicon tuner on IOE[4], if that * fails attach old simple PLL. */ @@ -746,8 +883,8 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) goto error; /* attach tuner */ - fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap, - &anysee_tda18212_config); + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, + &adap->dev->i2c_adap, &anysee_tda18212_config); if (fe) break; @@ -757,12 +894,15 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) goto error; /* attach tuner */ - fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1), - &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A); + fe = dvb_attach(dvb_pll_attach, adap->fe_adap[state->fe_id].fe, + (0xc0 >> 1), &adap->dev->i2c_adap, + DVB_PLL_SAMSUNG_DTOS403IH102A); break; case ANYSEE_HW_508TC: /* 18 */ + case ANYSEE_HW_508PTC: /* 21 */ /* E7 TC */ + /* E7 PTC */ /* enable tuner on IOE[4] */ ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10); @@ -770,20 +910,22 @@ static int anysee_tuner_attach(struct dvb_usb_adapter *adap) goto error; /* attach tuner */ - fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap, - &anysee_tda18212_config); + fe = dvb_attach(tda18212_attach, adap->fe_adap[state->fe_id].fe, + &adap->dev->i2c_adap, &anysee_tda18212_config); break; case ANYSEE_HW_508S2: /* 19 */ + case ANYSEE_HW_508PS2: /* 22 */ /* E7 S2 */ + /* E7 PS2 */ /* attach tuner */ - fe = dvb_attach(stv6110_attach, adap->fe, + fe = dvb_attach(stv6110_attach, adap->fe_adap[0].fe, &anysee_stv6110_config, &adap->dev->i2c_adap); if (fe) { /* attach LNB controller */ - fe = dvb_attach(isl6423_attach, adap->fe, + fe = dvb_attach(isl6423_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &anysee_isl6423_config); } @@ -885,6 +1027,23 @@ static struct dvb_usb_device_properties anysee_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 2, + .frontend_ctrl = anysee_frontend_ctrl, + .fe = {{ + .streaming_ctrl = anysee_streaming_ctrl, + .frontend_attach = anysee_frontend_attach, + .tuner_attach = anysee_tuner_attach, + .stream = { + .type = USB_BULK, + .count = 8, + .endpoint = 0x82, + .u = { + .bulk = { + .buffersize = (16*512), + } + } + }, + }, { .streaming_ctrl = anysee_streaming_ctrl, .frontend_attach = anysee_frontend_attach, .tuner_attach = anysee_tuner_attach, @@ -898,6 +1057,7 @@ static struct dvb_usb_device_properties anysee_properties = { } } }, + }}, } }, diff --git a/drivers/media/dvb/dvb-usb/anysee.h b/drivers/media/dvb/dvb-usb/anysee.h index a7673aa..57ee500 100644 --- a/drivers/media/dvb/dvb-usb/anysee.h +++ b/drivers/media/dvb/dvb-usb/anysee.h @@ -59,15 +59,18 @@ enum cmd { struct anysee_state { u8 hw; /* PCB ID */ u8 seq; + u8 fe_id:1; /* frondend ID */ }; -#define ANYSEE_HW_02 2 /* E30 */ -#define ANYSEE_HW_507CD 6 /* E30 Plus */ -#define ANYSEE_HW_507DC 10 /* E30 C Plus */ -#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */ -#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ -#define ANYSEE_HW_508TC 18 /* E7 TC */ -#define ANYSEE_HW_508S2 19 /* E7 S2 */ +#define ANYSEE_HW_507T 2 /* E30 */ +#define ANYSEE_HW_507CD 6 /* E30 Plus */ +#define ANYSEE_HW_507DC 10 /* E30 C Plus */ +#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */ +#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */ +#define ANYSEE_HW_508TC 18 /* E7 TC */ +#define ANYSEE_HW_508S2 19 /* E7 S2 */ +#define ANYSEE_HW_508PTC 21 /* E7 PTC Plus */ +#define ANYSEE_HW_508PS2 22 /* E7 PS2 Plus */ #define REG_IOA 0x80 /* Port A (bit addressable) */ #define REG_IOB 0x90 /* Port B (bit addressable) */ diff --git a/drivers/media/dvb/dvb-usb/au6610.c b/drivers/media/dvb/dvb-usb/au6610.c index 2351077..b779949 100644 --- a/drivers/media/dvb/dvb-usb/au6610.c +++ b/drivers/media/dvb/dvb-usb/au6610.c @@ -140,9 +140,9 @@ static struct zl10353_config au6610_zl10353_config = { static int au6610_zl10353_frontend_attach(struct dvb_usb_adapter *adap) { - adap->fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &au6610_zl10353_config, &adap->dev->i2c_adap); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -ENODEV; return 0; @@ -155,7 +155,7 @@ static struct qt1010_config au6610_qt1010_config = { static int au6610_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, + adap->fe_adap[0].fe, &adap->dev->i2c_adap, &au6610_qt1010_config) == NULL ? -ENODEV : 0; } @@ -204,6 +204,8 @@ static struct dvb_usb_device_properties au6610_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = au6610_zl10353_frontend_attach, .tuner_attach = au6610_qt1010_tuner_attach, @@ -219,6 +221,7 @@ static struct dvb_usb_device_properties au6610_properties = { } } }, + }}, } }, diff --git a/drivers/media/dvb/dvb-usb/az6027.c b/drivers/media/dvb/dvb-usb/az6027.c index 57e2444..bf67b4d 100644 --- a/drivers/media/dvb/dvb-usb/az6027.c +++ b/drivers/media/dvb/dvb-usb/az6027.c @@ -40,7 +40,6 @@ static const struct stb0899_s1_reg az6027_stb0899_s1_init_1[] = { { STB0899_DISRX_ST0 , 0x04 }, { STB0899_DISRX_ST1 , 0x00 }, { STB0899_DISPARITY , 0x00 }, - { STB0899_DISFIFO , 0x00 }, { STB0899_DISSTATUS , 0x20 }, { STB0899_DISF22 , 0x99 }, { STB0899_DISF22RX , 0xa8 }, @@ -782,7 +781,6 @@ static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) { u8 buf; - int ret; struct dvb_usb_adapter *adap = fe->dvb->priv; struct i2c_msg i2c_msg = { @@ -800,17 +798,17 @@ static int az6027_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) switch (voltage) { case SEC_VOLTAGE_13: buf = 1; - ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); + i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); break; case SEC_VOLTAGE_18: buf = 2; - ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); + i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); break; case SEC_VOLTAGE_OFF: buf = 0; - ret = i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); + i2c_transfer(&adap->dev->i2c_adap, &i2c_msg, 1); break; default: @@ -910,16 +908,16 @@ static int az6027_frontend_attach(struct dvb_usb_adapter *adap) az6027_frontend_reset(adap); deb_info("adap = %p, dev = %p\n", adap, adap->dev); - adap->fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap); + adap->fe_adap[0].fe = stb0899_attach(&az6027_stb0899_config, &adap->dev->i2c_adap); - if (adap->fe) { + if (adap->fe_adap[0].fe) { deb_info("found STB0899 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb0899_config.demod_address); - if (stb6100_attach(adap->fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) { + if (stb6100_attach(adap->fe_adap[0].fe, &az6027_stb6100_config, &adap->dev->i2c_adap)) { deb_info("found STB6100 DVB-S/DVB-S2 frontend @0x%02x", az6027_stb6100_config.tuner_address); - adap->fe->ops.set_voltage = az6027_set_voltage; + adap->fe_adap[0].fe->ops.set_voltage = az6027_set_voltage; az6027_ci_init(adap); } else { - adap->fe = NULL; + adap->fe_adap[0].fe = NULL; } } else warn("no front-end attached\n"); @@ -954,7 +952,6 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i = 0, j = 0, len = 0; - int ret; u16 index; u16 value; int length; @@ -990,7 +987,7 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff)); value = msg[i].addr + (msg[i].len << 8); length = msg[i + 1].len + 6; - ret = az6027_usb_in_op(d, req, value, index, data, length); + az6027_usb_in_op(d, req, value, index, data, length); len = msg[i + 1].len; for (j = 0; j < len; j++) msg[i + 1].buf[j] = data[j + 5]; @@ -1017,7 +1014,7 @@ static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n index = 0x0; value = msg[i].addr; length = msg[i].len + 6; - ret = az6027_usb_in_op(d, req, value, index, data, length); + az6027_usb_in_op(d, req, value, index, data, length); len = msg[i].len; for (j = 0; j < len; j++) msg[i].buf[j] = data[j + 5]; @@ -1106,6 +1103,8 @@ static struct dvb_usb_device_properties az6027_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = az6027_streaming_ctrl, .frontend_attach = az6027_frontend_attach, @@ -1120,6 +1119,7 @@ static struct dvb_usb_device_properties az6027_properties = { } } }, + }}, } }, /* diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c index 6d1a304..57afb5a 100644 --- a/drivers/media/dvb/dvb-usb/ce6230.c +++ b/drivers/media/dvb/dvb-usb/ce6230.c @@ -186,9 +186,9 @@ static struct zl10353_config ce6230_zl10353_config = { static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap) { deb_info("%s:\n", __func__); - adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config, + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config, &adap->dev->i2c_adap); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -ENODEV; return 0; } @@ -214,7 +214,7 @@ static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) { int ret; deb_info("%s:\n", __func__); - ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap, + ret = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0; return ret; } @@ -273,6 +273,8 @@ static struct dvb_usb_device_properties ce6230_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = ce6230_zl10353_frontend_attach, .tuner_attach = ce6230_mxl5003s_tuner_attach, .stream = { @@ -285,6 +287,7 @@ static struct dvb_usb_device_properties ce6230_properties = { } } }, + }}, } }, diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-core.c b/drivers/media/dvb/dvb-usb/cinergyT2-core.c index 16f2ce2..f9d9050 100644 --- a/drivers/media/dvb/dvb-usb/cinergyT2-core.c +++ b/drivers/media/dvb/dvb-usb/cinergyT2-core.c @@ -69,7 +69,7 @@ static int cinergyt2_frontend_attach(struct dvb_usb_adapter *adap) char state[3]; int ret; - adap->fe = cinergyt2_fe_attach(adap->dev); + adap->fe_adap[0].fe = cinergyt2_fe_attach(adap->dev); ret = dvb_usb_generic_rw(adap->dev, query, sizeof(query), state, sizeof(state), 0); @@ -198,6 +198,8 @@ static struct dvb_usb_device_properties cinergyt2_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cinergyt2_streaming_ctrl, .frontend_attach = cinergyt2_frontend_attach, @@ -212,6 +214,7 @@ static struct dvb_usb_device_properties cinergyt2_properties = { } } }, + }}, } }, diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index acb5fb2..9f2a02c 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -347,7 +347,7 @@ static void cxusb_d680_dmb_drain_message(struct dvb_usb_device *d) static void cxusb_d680_dmb_drain_video(struct dvb_usb_device *d) { - struct usb_data_stream_properties *p = &d->props.adapter[0].stream; + struct usb_data_stream_properties *p = &d->props.adapter[0].fe[0].stream; const int timeout = 100; const int junk_len = p->u.bulk.buffersize; u8 *junk; @@ -725,7 +725,7 @@ static struct max2165_config mygica_d689_max2165_cfg = { /* Callbacks for DVB USB */ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(simple_tuner_attach, adap->fe, + dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3); return 0; @@ -733,27 +733,27 @@ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) static int cxusb_dee1601_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(dvb_pll_attach, adap->fe, 0x61, + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_THOMSON_DTT7579); return 0; } static int cxusb_lgz201_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_LG_Z201); + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_LG_Z201); return 0; } static int cxusb_dtt7579_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(dvb_pll_attach, adap->fe, 0x60, + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, NULL, DVB_PLL_THOMSON_DTT7579); return 0; } static int cxusb_lgh064f_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(simple_tuner_attach, adap->fe, + dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0x61, TUNER_LG_TDVS_H06XF); return 0; } @@ -795,9 +795,9 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) }; /* FIXME: generalize & move to common area */ - adap->fe->callback = dvico_bluebird_xc2028_callback; + adap->fe_adap[0].fe->callback = dvico_bluebird_xc2028_callback; - fe = dvb_attach(xc2028_attach, adap->fe, &cfg); + fe = dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &cfg); if (fe == NULL || fe->ops.tuner_ops.set_config == NULL) return -EIO; @@ -808,7 +808,7 @@ static int cxusb_dvico_xc3028_tuner_attach(struct dvb_usb_adapter *adap) static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(mxl5005s_attach, adap->fe, + dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &aver_a868r_tuner); return 0; } @@ -816,7 +816,7 @@ static int cxusb_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) { struct dvb_frontend *fe; - fe = dvb_attach(mxl5005s_attach, adap->fe, + fe = dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &d680_dmb_tuner); return (fe == NULL) ? -EIO : 0; } @@ -824,7 +824,7 @@ static int cxusb_d680_dmb_tuner_attach(struct dvb_usb_adapter *adap) static int cxusb_mygica_d689_tuner_attach(struct dvb_usb_adapter *adap) { struct dvb_frontend *fe; - fe = dvb_attach(max2165_attach, adap->fe, + fe = dvb_attach(max2165_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &mygica_d689_max2165_cfg); return (fe == NULL) ? -EIO : 0; } @@ -837,8 +837,9 @@ static int cxusb_cx22702_frontend_attach(struct dvb_usb_adapter *adap) cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, &b, 1); - if ((adap->fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, - &adap->dev->i2c_adap)) != NULL) + adap->fe_adap[0].fe = dvb_attach(cx22702_attach, &cxusb_cx22702_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) return 0; return -EIO; @@ -851,8 +852,10 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - if ((adap->fe = dvb_attach(lgdt330x_attach, &cxusb_lgdt3303_config, - &adap->dev->i2c_adap)) != NULL) + adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, + &cxusb_lgdt3303_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) return 0; return -EIO; @@ -860,9 +863,9 @@ static int cxusb_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) static int cxusb_aver_lgdt3303_frontend_attach(struct dvb_usb_adapter *adap) { - adap->fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config, + adap->fe_adap[0].fe = dvb_attach(lgdt330x_attach, &cxusb_aver_lgdt3303_config, &adap->dev->i2c_adap); - if (adap->fe != NULL) + if (adap->fe_adap[0].fe != NULL) return 0; return -EIO; @@ -876,8 +879,9 @@ static int cxusb_mt352_frontend_attach(struct dvb_usb_adapter *adap) cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - if ((adap->fe = dvb_attach(mt352_attach, &cxusb_mt352_config, - &adap->dev->i2c_adap)) != NULL) + adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_mt352_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) return 0; return -EIO; @@ -890,11 +894,15 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_adapter *adap) cxusb_ctrl_msg(adap->dev, CMD_DIGITAL, NULL, 0, NULL, 0); - if (((adap->fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, - &adap->dev->i2c_adap)) != NULL) || - ((adap->fe = dvb_attach(zl10353_attach, - &cxusb_zl10353_dee1601_config, - &adap->dev->i2c_adap)) != NULL)) + adap->fe_adap[0].fe = dvb_attach(mt352_attach, &cxusb_dee1601_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) + return 0; + + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, + &cxusb_zl10353_dee1601_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) return 0; return -EIO; @@ -917,9 +925,11 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); - if ((adap->fe = dvb_attach(zl10353_attach, - &cxusb_zl10353_xc3028_config_no_i2c_gate, - &adap->dev->i2c_adap)) == NULL) + adap->fe_adap[0].fe = + dvb_attach(zl10353_attach, + &cxusb_zl10353_xc3028_config_no_i2c_gate, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) == NULL) return -EIO; /* try to determine if there is no IR decoder on the I2C bus */ @@ -1031,9 +1041,9 @@ static int cxusb_dualdig4_rev2_frontend_attach(struct dvb_usb_adapter *adap) return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &cxusb_dualdig4_rev2_config); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -EIO; return 0; @@ -1084,15 +1094,15 @@ static int cxusb_dualdig4_rev2_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; struct i2c_adapter *tun_i2c = - dib7000p_get_i2c_master(adap->fe, + dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config) == NULL) return -ENODEV; - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override; return 0; } @@ -1108,14 +1118,16 @@ static int cxusb_nano2_frontend_attach(struct dvb_usb_adapter *adap) cxusb_bluebird_gpio_pulse(adap->dev, 0x01, 1); cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); - if ((adap->fe = dvb_attach(zl10353_attach, - &cxusb_zl10353_xc3028_config, - &adap->dev->i2c_adap)) != NULL) + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, + &cxusb_zl10353_xc3028_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) return 0; - if ((adap->fe = dvb_attach(mt352_attach, - &cxusb_mt352_xc3028_config, - &adap->dev->i2c_adap)) != NULL) + adap->fe_adap[0].fe = dvb_attach(mt352_attach, + &cxusb_mt352_xc3028_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) return 0; return -EIO; @@ -1150,7 +1162,7 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint)); + usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); /* Drain USB pipes to avoid hang after reboot */ for (n = 0; n < 5; n++) { @@ -1172,8 +1184,8 @@ static int cxusb_d680_dmb_frontend_attach(struct dvb_usb_adapter *adap) msleep(100); /* Attach frontend */ - adap->fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap); - if (adap->fe == NULL) + adap->fe_adap[0].fe = dvb_attach(lgs8gxx_attach, &d680_lgs8gl5_cfg, &d->i2c_adap); + if (adap->fe_adap[0].fe == NULL) return -EIO; return 0; @@ -1207,7 +1219,7 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint)); usb_clear_halt(d->udev, - usb_rcvbulkpipe(d->udev, d->props.adapter[0].stream.endpoint)); + usb_rcvbulkpipe(d->udev, d->props.adapter[0].fe[0].stream.endpoint)); /* Reset the tuner */ @@ -1223,9 +1235,9 @@ static int cxusb_mygica_d689_frontend_attach(struct dvb_usb_adapter *adap) msleep(100); /* Attach frontend */ - adap->fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg, + adap->fe_adap[0].fe = dvb_attach(atbm8830_attach, &mygica_d689_atbm8830_cfg, &d->i2c_adap); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -EIO; return 0; @@ -1383,6 +1395,8 @@ static struct dvb_usb_device_properties cxusb_medion_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_cx22702_frontend_attach, .tuner_attach = cxusb_fmd1216me_tuner_attach, @@ -1397,7 +1411,7 @@ static struct dvb_usb_device_properties cxusb_medion_properties = { } } }, - + }}, }, }, .power_ctrl = cxusb_power_ctrl, @@ -1429,6 +1443,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_lgdt3303_frontend_attach, .tuner_attach = cxusb_lgh064f_tuner_attach, @@ -1444,6 +1460,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgh064f_properties = { } } }, + }}, }, }, @@ -1483,6 +1500,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_dee1601_frontend_attach, .tuner_attach = cxusb_dee1601_tuner_attach, @@ -1497,6 +1516,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dee1601_properties = { } } }, + }}, }, }, @@ -1544,6 +1564,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_mt352_frontend_attach, .tuner_attach = cxusb_lgz201_tuner_attach, @@ -1559,6 +1581,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_lgz201_properties = { } } }, + }}, }, }, .power_ctrl = cxusb_bluebird_power_ctrl, @@ -1596,6 +1619,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_mt352_frontend_attach, .tuner_attach = cxusb_dtt7579_tuner_attach, @@ -1611,6 +1636,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dtt7579_properties = { } } }, + }}, }, }, .power_ctrl = cxusb_bluebird_power_ctrl, @@ -1645,6 +1671,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_dualdig4_frontend_attach, .tuner_attach = cxusb_dvico_xc3028_tuner_attach, @@ -1659,6 +1687,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_dualdig4_properties = { } } }, + }}, }, }, @@ -1695,6 +1724,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_nano2_frontend_attach, .tuner_attach = cxusb_dvico_xc3028_tuner_attach, @@ -1709,6 +1740,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_properties = { } } }, + }}, }, }, @@ -1747,6 +1779,8 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_nano2_frontend_attach, .tuner_attach = cxusb_dvico_xc3028_tuner_attach, @@ -1761,6 +1795,7 @@ static struct dvb_usb_device_properties cxusb_bluebird_nano2_needsfirmware_prope } } }, + }}, }, }, @@ -1796,6 +1831,8 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_aver_streaming_ctrl, .frontend_attach = cxusb_aver_lgdt3303_frontend_attach, .tuner_attach = cxusb_mxl5003s_tuner_attach, @@ -1810,7 +1847,7 @@ static struct dvb_usb_device_properties cxusb_aver_a868r_properties = { } } }, - + }}, }, }, .power_ctrl = cxusb_aver_power_ctrl, @@ -1839,10 +1876,12 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { .num_adapters = 1, .adapter = { { + .size_of_priv = sizeof(struct dib0700_adapter_state), + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_streaming_ctrl, .frontend_attach = cxusb_dualdig4_rev2_frontend_attach, .tuner_attach = cxusb_dualdig4_rev2_tuner_attach, - .size_of_priv = sizeof(struct dib0700_adapter_state), /* parameter for the MPEG2-data transfer */ .stream = { .type = USB_BULK, @@ -1854,6 +1893,7 @@ struct dvb_usb_device_properties cxusb_bluebird_dualdig4_rev2_properties = { } } }, + }}, }, }, @@ -1889,6 +1929,8 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, .frontend_attach = cxusb_d680_dmb_frontend_attach, .tuner_attach = cxusb_d680_dmb_tuner_attach, @@ -1904,6 +1946,7 @@ static struct dvb_usb_device_properties cxusb_d680_dmb_properties = { } } }, + }}, }, }, @@ -1940,6 +1983,8 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = cxusb_d680_dmb_streaming_ctrl, .frontend_attach = cxusb_mygica_d689_frontend_attach, .tuner_attach = cxusb_mygica_d689_tuner_attach, @@ -1955,6 +2000,7 @@ static struct dvb_usb_device_properties cxusb_mygica_d689_properties = { } } }, + }}, }, }, diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c index a224e94..156cbfc 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_core.c +++ b/drivers/media/dvb/dvb-usb/dib0700_core.c @@ -31,7 +31,7 @@ int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion, int ret; if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -117,7 +117,7 @@ int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_ int ret; if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -138,7 +138,7 @@ static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets) if (st->fw_version >= 0x10201) { if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -227,7 +227,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg, } else { /* Write request */ if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } st->buf[0] = REQUEST_NEW_I2C_WRITE; @@ -273,7 +273,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap, if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -368,7 +368,7 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll, int ret; if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -400,7 +400,7 @@ int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz) return -EINVAL; if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -528,13 +528,13 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters; adap_num++) { if (fw_version >= 0x10201) { - dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size; + dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 188*nb_packet_buffer_size; } else { /* for fw version older than 1.20.1, * the buffersize has to be n times 512 */ - dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512; - if (dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize < 512) - dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 512; + dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512; + if (dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize < 512) + dib0700_devices[i].adapter[adap_num].fe[0].stream.u.bulk.buffersize = 512; } } } @@ -560,7 +560,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } if (mutex_lock_interruptible(&adap->dev->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } @@ -579,18 +579,18 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); st->channel_state &= ~0x3; - if ((adap->stream.props.endpoint != 2) - && (adap->stream.props.endpoint != 3)) { - deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint); + if ((adap->fe_adap[0].stream.props.endpoint != 2) + && (adap->fe_adap[0].stream.props.endpoint != 3)) { + deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint); if (onoff) st->channel_state |= 1 << (adap->id); else st->channel_state |= 1 << ~(adap->id); } else { if (onoff) - st->channel_state |= 1 << (adap->stream.props.endpoint-2); + st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2); else - st->channel_state |= 1 << (3-adap->stream.props.endpoint); + st->channel_state |= 1 << (3-adap->fe_adap[0].stream.props.endpoint); } st->buf[2] |= st->channel_state; @@ -610,7 +610,7 @@ int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type) int new_proto, ret; if (mutex_lock_interruptible(&d->usb_mutex) < 0) { - deb_info("could not acquire lock"); + err("could not acquire lock"); return 0; } diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c index c519ad5..f313182 100644 --- a/drivers/media/dvb/dvb-usb/dib0700_devices.c +++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c @@ -17,6 +17,7 @@ #include "mt2266.h" #include "tuner-xc2028.h" #include "xc5000.h" +#include "xc4000.h" #include "s5h1411.h" #include "dib0070.h" #include "dib0090.h" @@ -100,7 +101,7 @@ static int bristol_frontend_attach(struct dvb_usb_adapter *adap) } } st->mt2060_if1[adap->id] = 1220; - return (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, + return (adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, (10 + adap->id) << 1, &bristol_dib3000mc_config[adap->id])) == NULL ? -ENODEV : 0; } @@ -117,15 +118,16 @@ static int eeprom_read(struct i2c_adapter *adap,u8 adrs,u8 *pval) static int bristol_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *prim_i2c = &adap->dev->i2c_adap; - struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); + struct i2c_adapter *tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1); s8 a; int if1=1220; if (adap->dev->udev->descriptor.idVendor == cpu_to_le16(USB_VID_HAUPPAUGE) && adap->dev->udev->descriptor.idProduct == cpu_to_le16(USB_PID_HAUPPAUGE_NOVA_T_500_2)) { if (!eeprom_read(prim_i2c,0x59 + adap->id,&a)) if1=1220+a; } - return dvb_attach(mt2060_attach,adap->fe, tun_i2c,&bristol_mt2060_config[adap->id], - if1) == NULL ? -ENODEV : 0; + return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, + &bristol_mt2060_config[adap->id], if1) == NULL ? + -ENODEV : 0; } /* STK7700D: Pinnacle/Terratec/Hauppauge Dual DVB-T Diversity */ @@ -278,10 +280,12 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap) } } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), - &stk7700d_dib7000p_mt2266_config[adap->id]); + adap->fe_adap[0].fe = + dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80 + (adap->id << 1), + &stk7700d_dib7000p_mt2266_config[adap->id]); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) @@ -305,17 +309,19 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap) } } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1), - &stk7700d_dib7000p_mt2266_config[adap->id]); + adap->fe_adap[0].fe = + dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, + 0x80 + (adap->id << 1), + &stk7700d_dib7000p_mt2266_config[adap->id]); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk7700d_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; - tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); - return dvb_attach(mt2266_attach, adap->fe, tun_i2c, + tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + return dvb_attach(mt2266_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700d_mt2266_config[adap->id]) == NULL ? -ENODEV : 0; } @@ -395,8 +401,8 @@ static int stk7700ph_xc3028_callback(void *ptr, int component, switch (command) { case XC2028_TUNER_RESET: /* Send the tuner in then out of reset */ - dib7000p_set_gpio(adap->fe, 8, 0, 0); msleep(10); - dib7000p_set_gpio(adap->fe, 8, 0, 1); + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); msleep(10); + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); break; case XC2028_RESET_CLK: break; @@ -446,25 +452,25 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap) return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7700ph_dib7700_xc3028_config); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk7700ph_tuner_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *tun_i2c; - tun_i2c = dib7000p_get_i2c_master(adap->fe, + tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); stk7700ph_xc3028_config.i2c_adap = tun_i2c; /* FIXME: generalize & move to common area */ - adap->fe->callback = stk7700ph_xc3028_callback; + adap->fe_adap[0].fe->callback = stk7700ph_xc3028_callback; - return dvb_attach(xc2028_attach, adap->fe, &stk7700ph_xc3028_config) + return dvb_attach(xc2028_attach, adap->fe_adap[0].fe, &stk7700ph_xc3028_config) == NULL ? -ENODEV : 0; } @@ -684,12 +690,12 @@ static int stk7700p_frontend_attach(struct dvb_usb_adapter *adap) st->mt2060_if1[0] = 1220; if (dib7000pc_detection(&adap->dev->i2c_adap)) { - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000p_config); st->is_dib7000pc = 1; } else - adap->fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); + adap->fe_adap[0].fe = dvb_attach(dib7000m_attach, &adap->dev->i2c_adap, 18, &stk7700p_dib7000m_config); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static struct mt2060_config stk7700p_mt2060_config = { @@ -708,11 +714,11 @@ static int stk7700p_tuner_attach(struct dvb_usb_adapter *adap) if (!eeprom_read(prim_i2c,0x58,&a)) if1=1220+a; } if (st->is_dib7000pc) - tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); else - tun_i2c = dib7000m_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + tun_i2c = dib7000m_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); - return dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk7700p_mt2060_config, + return dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk7700p_mt2060_config, if1) == NULL ? -ENODEV : 0; } @@ -842,33 +848,33 @@ static int dib7770_set_param_override(struct dvb_frontend *fe, static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, + struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, - &dib7770p_dib0070_config) == NULL) + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, + &dib7770p_dib0070_config) == NULL) return -ENODEV; - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7770_set_param_override; return 0; } static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (adap->id == 0) { - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL) + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[0]) == NULL) return -ENODEV; } else { - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL) + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib7070p_dib0070_config[1]) == NULL) return -ENODEV; } - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7070_set_param_override; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7070_set_param_override; return 0; } @@ -877,26 +883,26 @@ static int stk7700p_pid_filter(struct dvb_usb_adapter *adapter, int index, { struct dib0700_state *st = adapter->dev->priv; if (st->is_dib7000pc) - return dib7000p_pid_filter(adapter->fe, index, pid, onoff); - return dib7000m_pid_filter(adapter->fe, index, pid, onoff); + return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); + return dib7000m_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk7700p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { struct dib0700_state *st = adapter->dev->priv; if (st->is_dib7000pc) - return dib7000p_pid_filter_ctrl(adapter->fe, onoff); - return dib7000m_pid_filter_ctrl(adapter->fe, onoff); + return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); + return dib7000m_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static int stk70x0p_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib7000p_pid_filter(adapter->fe, index, pid, onoff); + return dib7000p_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk70x0p_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib7000p_pid_filter_ctrl(adapter->fe, onoff); + return dib7000p_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static struct dibx000_bandwidth_config dib7070_bw_config_12_mhz = { @@ -954,9 +960,9 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap) return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7070p_dib7000p_config); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } /* STK7770P */ @@ -1006,9 +1012,9 @@ static int stk7770p_frontend_attach(struct dvb_usb_adapter *adap) return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &dib7770p_dib7000p_config); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } /* DIB807x generic */ @@ -1224,34 +1230,34 @@ static int dib807x_set_param_override(struct dvb_frontend *fe, static int dib807x_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, + struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); if (adap->id == 0) { - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib807x_dib0070_config[0]) == NULL) return -ENODEV; } else { - if (dvb_attach(dib0070_attach, adap->fe, tun_i2c, + if (dvb_attach(dib0070_attach, adap->fe_adap[0].fe, tun_i2c, &dib807x_dib0070_config[1]) == NULL) return -ENODEV; } - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib807x_set_param_override; return 0; } static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib8000_pid_filter(adapter->fe, index, pid, onoff); + return dib8000_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib8000_pid_filter_ctrl(adapter->fe, onoff); + return dib8000_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } /* STK807x */ @@ -1275,10 +1281,10 @@ static int stk807x_frontend_attach(struct dvb_usb_adapter *adap) dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); - adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } /* STK807xPVR */ @@ -1304,10 +1310,10 @@ static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap) /* initialize IC 0 */ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x80); - adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib807x_dib8000_config[0]); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) @@ -1315,10 +1321,10 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap) /* initialize IC 1 */ dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x82); - adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib807x_dib8000_config[1]); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } /* STK8096GP */ @@ -1545,13 +1551,13 @@ static int dib8096_set_param_override(struct dvb_frontend *fe, static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); + struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); - if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override; return 0; } @@ -1574,30 +1580,30 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); - adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; struct i2c_adapter *tun_i2c; - struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1); + struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe_adap[0].fe, 1); if (fe_slave) { tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1); if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; - fe_slave->dvb = adap->fe->dvb; + fe_slave->dvb = adap->fe_adap[0].fe->dvb; fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override; } - tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); - if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) + tun_i2c = dib8000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_TUNER, 1); + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &dib809x_dib0090_config) == NULL) return -ENODEV; - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib8096_set_param_override; return 0; } @@ -1625,12 +1631,12 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80); - adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); - if (adap->fe == NULL) + adap->fe_adap[0].fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]); + if (adap->fe_adap[0].fe == NULL) return -ENODEV; fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]); - dib8000_set_slave_frontend(adap->fe, fe_slave); + dib8000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave); return fe_slave == NULL ? -ENODEV : 0; } @@ -1638,12 +1644,12 @@ static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap) /* STK9090M */ static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff) { - return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff); + return dib9000_fw_pid_filter(adapter->fe_adap[0].fe, index, pid, onoff); } static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff) { - return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff); + return dib9000_fw_pid_filter_ctrl(adapter->fe_adap[0].fe, onoff); } static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff) @@ -1855,15 +1861,15 @@ static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; - adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config); + adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *state = adap->priv; - struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe); + struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe); u16 data_dib190[10] = { 1, 0x1374, 2, 0x01a2, @@ -1872,13 +1878,13 @@ static int dib9090_tuner_attach(struct dvb_usb_adapter *adap) 8, 0x0486, }; - if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL) + if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &dib9090_dib0090_config) == NULL) return -ENODEV; - i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); + i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0) return -ENODEV; dib0700_set_i2c_speed(adap->dev, 2000); - if (dib9000_firmware_post_pll_init(adap->fe) < 0) + if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; release_firmware(state->frontend_firmware); return 0; @@ -1924,16 +1930,16 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data; dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80); - adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]); + adap->fe_adap[0].fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -ENODEV; - i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0); + i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0); dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82); fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]); - dib9000_set_slave_frontend(adap->fe, fe_slave); + dib9000_set_slave_frontend(adap->fe_adap[0].fe, fe_slave); return fe_slave == NULL ? -ENODEV : 0; } @@ -1950,26 +1956,26 @@ static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap) 0, 0x00ef, 8, 0x0406, }; - i2c = dib9000_get_tuner_interface(adap->fe); - if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL) + i2c = dib9000_get_tuner_interface(adap->fe_adap[0].fe); + if (dvb_attach(dib0090_fw_register, adap->fe_adap[0].fe, i2c, &nim9090md_dib0090_config[0]) == NULL) return -ENODEV; - i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); + i2c = dib9000_get_i2c_master(adap->fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0); if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0) return -ENODEV; dib0700_set_i2c_speed(adap->dev, 2000); - if (dib9000_firmware_post_pll_init(adap->fe) < 0) + if (dib9000_firmware_post_pll_init(adap->fe_adap[0].fe) < 0) return -ENODEV; - fe_slave = dib9000_get_slave_frontend(adap->fe, 1); + fe_slave = dib9000_get_slave_frontend(adap->fe_adap[0].fe, 1); if (fe_slave != NULL) { - i2c = dib9000_get_component_bus_interface(adap->fe); + i2c = dib9000_get_component_bus_interface(adap->fe_adap[0].fe); dib9000_set_i2c_adapter(fe_slave, i2c); i2c = dib9000_get_tuner_interface(fe_slave); if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL) return -ENODEV; - fe_slave->dvb = adap->fe->dvb; - dib9000_fw_set_component_bus_speed(adap->fe, 2000); + fe_slave->dvb = adap->fe_adap[0].fe->dvb; + dib9000_fw_set_component_bus_speed(adap->fe_adap[0].fe, 2000); if (dib9000_firmware_post_pll_init(fe_slave) < 0) return -ENODEV; } @@ -2392,23 +2398,23 @@ static int nim7090_frontend_attach(struct dvb_usb_adapter *adap) err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int nim7090_tuner_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); + struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); - if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL) + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &nim7090_dib0090_config) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe, 8, 0, 1); + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; return 0; } @@ -2438,11 +2444,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) } dib0700_set_i2c_speed(adap->dev, 340); - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); - if (adap->fe == NULL) + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); + if (adap->fe_adap[0].fe == NULL) return -ENODEV; - dib7090_slave_reset(adap->fe); + dib7090_slave_reset(adap->fe_adap[0].fe); return 0; } @@ -2451,50 +2457,50 @@ static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap) { struct i2c_adapter *i2c; - if (adap->dev->adapter[0].fe == NULL) { + if (adap->dev->adapter[0].fe_adap[0].fe == NULL) { err("the master dib7090 has to be initialized first"); return -ENODEV; /* the master device has not been initialized */ } - i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); + i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe_adap[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1); if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) { err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__); return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]); dib0700_set_i2c_speed(adap->dev, 200); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); + struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); - if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL) + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe, 8, 0, 1); + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; return 0; } static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap) { struct dib0700_adapter_state *st = adap->priv; - struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe); + struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe_adap[0].fe); - if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL) + if (dvb_attach(dib0090_register, adap->fe_adap[0].fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL) return -ENODEV; - dib7000p_set_gpio(adap->fe, 8, 0, 1); + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); - st->set_param_save = adap->fe->ops.tuner_ops.set_params; - adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup; + st->set_param_save = adap->fe_adap[0].fe->ops.tuner_ops.set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = dib7090_agc_startup; return 0; } @@ -2554,14 +2560,14 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap) return -ENODEV; } - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); - return adap->fe == NULL ? -ENODEV : 0; + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]); + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int stk7070pd_frontend_attach1(struct dvb_usb_adapter *adap) { - adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]); - return adap->fe == NULL ? -ENODEV : 0; + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x82, &stk7070pd_dib7000p_config[1]); + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } /* S5H1411 */ @@ -2616,9 +2622,9 @@ static int s5h1411_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1); /* GPIOs are initialized, do the attach */ - adap->fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config, + adap->fe_adap[0].fe = dvb_attach(s5h1411_attach, &pinnacle_801e_config, &adap->dev->i2c_adap); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int dib0700_xc5000_tuner_callback(void *priv, int component, @@ -2648,13 +2654,163 @@ static struct xc5000_config s5h1411_xc5000_tunerconfig = { static int xc5000_tuner_attach(struct dvb_usb_adapter *adap) { /* FIXME: generalize & move to common area */ - adap->fe->callback = dib0700_xc5000_tuner_callback; + adap->fe_adap[0].fe->callback = dib0700_xc5000_tuner_callback; - return dvb_attach(xc5000_attach, adap->fe, &adap->dev->i2c_adap, + return dvb_attach(xc5000_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &s5h1411_xc5000_tunerconfig) == NULL ? -ENODEV : 0; } +static int dib0700_xc4000_tuner_callback(void *priv, int component, + int command, int arg) +{ + struct dvb_usb_adapter *adap = priv; + + if (command == XC4000_TUNER_RESET) { + /* Reset the tuner */ + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 0); + msleep(10); + dib7000p_set_gpio(adap->fe_adap[0].fe, 8, 0, 1); + } else { + err("xc4000: unknown tuner callback command: %d\n", command); + return -EINVAL; + } + + return 0; +} + +static struct dibx000_agc_config stk7700p_7000p_xc4000_agc_config = { + .band_caps = BAND_UHF | BAND_VHF, + .setup = 0x64, + .inv_gain = 0x02c8, + .time_stabiliz = 0x15, + .alpha_level = 0x00, + .thlock = 0x76, + .wbd_inv = 0x01, + .wbd_ref = 0x0b33, + .wbd_sel = 0x00, + .wbd_alpha = 0x02, + .agc1_max = 0x00, + .agc1_min = 0x00, + .agc2_max = 0x9b26, + .agc2_min = 0x26ca, + .agc1_pt1 = 0x00, + .agc1_pt2 = 0x00, + .agc1_pt3 = 0x00, + .agc1_slope1 = 0x00, + .agc1_slope2 = 0x00, + .agc2_pt1 = 0x00, + .agc2_pt2 = 0x80, + .agc2_slope1 = 0x1d, + .agc2_slope2 = 0x1d, + .alpha_mant = 0x11, + .alpha_exp = 0x1b, + .beta_mant = 0x17, + .beta_exp = 0x33, + .perform_agc_softsplit = 0x00, +}; + +static struct dibx000_bandwidth_config stk7700p_xc4000_pll_config = { + 60000, 30000, /* internal, sampling */ + 1, 8, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass */ + 0, 0, 1, 1, 0, /* misc: refdiv, bypclk_div, IO_CLK_en_core, */ + /* ADClkSrc, modulo */ + (3 << 14) | (1 << 12) | 524, /* sad_cfg: refsel, sel, freq_15k */ + 39370534, /* ifreq */ + 20452225, /* timf */ + 30000000 /* xtal */ +}; + +/* FIXME: none of these inputs are validated yet */ +static struct dib7000p_config pctv_340e_config = { + .output_mpeg2_in_188_bytes = 1, + + .agc_config_count = 1, + .agc = &stk7700p_7000p_xc4000_agc_config, + .bw = &stk7700p_xc4000_pll_config, + + .gpio_dir = DIB7000M_GPIO_DEFAULT_DIRECTIONS, + .gpio_val = DIB7000M_GPIO_DEFAULT_VALUES, + .gpio_pwm_pos = DIB7000M_GPIO_DEFAULT_PWM_POS, +}; + +/* PCTV 340e GPIOs map: + dib0700: + GPIO2 - CX25843 sleep + GPIO3 - CS5340 reset + GPIO5 - IRD + GPIO6 - Power Supply + GPIO8 - LNA (1=off 0=on) + GPIO10 - CX25843 reset + dib7000: + GPIO8 - xc4000 reset + */ +static int pctv340e_frontend_attach(struct dvb_usb_adapter *adap) +{ + struct dib0700_state *st = adap->dev->priv; + + /* Power Supply on */ + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0); + msleep(50); + dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1); + msleep(100); /* Allow power supply to settle before probing */ + + /* cx25843 reset */ + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0); + msleep(1); /* cx25843 datasheet say 350us required */ + dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); + + /* LNA off for now */ + dib0700_set_gpio(adap->dev, GPIO8, GPIO_OUT, 1); + + /* Put the CX25843 to sleep for now since we're in digital mode */ + dib0700_set_gpio(adap->dev, GPIO2, GPIO_OUT, 1); + + /* FIXME: not verified yet */ + dib0700_ctrl_clock(adap->dev, 72, 1); + + msleep(500); + + if (dib7000pc_detection(&adap->dev->i2c_adap) == 0) { + /* Demodulator not found for some reason? */ + return -ENODEV; + } + + adap->fe_adap[0].fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x12, + &pctv_340e_config); + st->is_dib7000pc = 1; + + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; +} + +static struct xc4000_config dib7000p_xc4000_tunerconfig = { + .i2c_address = 0x61, + .default_pm = 1, + .dvb_amplitude = 0, + .set_smoothedcvbs = 0, + .if_khz = 5400 +}; + +static int xc4000_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct i2c_adapter *tun_i2c; + + /* The xc4000 is not on the main i2c bus */ + tun_i2c = dib7000p_get_i2c_master(adap->fe_adap[0].fe, + DIBX000_I2C_INTERFACE_TUNER, 1); + if (tun_i2c == NULL) { + printk(KERN_ERR "Could not reach tuner i2c bus\n"); + return 0; + } + + /* Setup the reset callback */ + adap->fe_adap[0].fe->callback = dib0700_xc4000_tuner_callback; + + return dvb_attach(xc4000_attach, adap->fe_adap[0].fe, tun_i2c, + &dib7000p_xc4000_tunerconfig) + == NULL ? -ENODEV : 0; +} + static struct lgdt3305_config hcw_lgdt3305_config = { .i2c_addr = 0x0e, .mpeg_mode = LGDT3305_MPEG_PARALLEL, @@ -2706,16 +2862,16 @@ static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap) dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1); msleep(30); - adap->fe = dvb_attach(lgdt3305_attach, + adap->fe_adap[0].fe = dvb_attach(lgdt3305_attach, &hcw_lgdt3305_config, &adap->dev->i2c_adap); - return adap->fe == NULL ? -ENODEV : 0; + return adap->fe_adap[0].fe == NULL ? -ENODEV : 0; } static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap) { - return dvb_attach(mxl5007t_attach, adap->fe, + return dvb_attach(mxl5007t_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0x60, &hcw_mxl5007t_config) == NULL ? -ENODEV : 0; } @@ -2802,6 +2958,8 @@ struct usb_device_id dib0700_usb_id_table[] = { { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) }, { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) }, /* 75 */{ USB_DEVICE(USB_VID_MEDION, USB_PID_CREATIX_CTX1921) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E) }, + { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV340E_SE) }, { 0 } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); @@ -2836,6 +2994,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk7700p_pid_filter, @@ -2844,6 +3004,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = stk7700p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }}, }, }, @@ -2897,15 +3058,21 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = bristol_frontend_attach, .tuner_attach = bristol_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }}, }, { + .num_frontends = 1, + .fe = {{ .frontend_attach = bristol_frontend_attach, .tuner_attach = bristol_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + }}, } }, @@ -2931,6 +3098,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -2939,7 +3108,10 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = stk7700d_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }}, }, { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -2948,6 +3120,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = stk7700d_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x03), + }}, } }, @@ -2990,6 +3163,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -2998,6 +3173,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = stk7700d_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }}, }, }, @@ -3032,6 +3208,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3040,7 +3218,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7070p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -3108,6 +3286,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3116,7 +3296,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7070p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, }, @@ -3152,6 +3332,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3160,9 +3342,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7070p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3171,7 +3355,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7070p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -3220,6 +3404,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3228,9 +3414,11 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7070p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3239,7 +3427,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7070p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), } }, @@ -3267,6 +3455,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3275,7 +3465,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = stk7700ph_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3335,11 +3525,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = s5h1411_frontend_attach, .tuner_attach = xc5000_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3371,11 +3563,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = lgdt3305_frontend_attach, .tuner_attach = mxl5007t_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3397,6 +3591,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk70x0p_pid_filter, @@ -3405,7 +3601,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib7770p_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3447,6 +3643,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk80xx_pid_filter, @@ -3455,7 +3653,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib807x_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3491,6 +3689,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk80xx_pid_filter, @@ -3499,11 +3699,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib807x_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .pid_filter = stk80xx_pid_filter, @@ -3512,7 +3714,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib807x_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3540,6 +3742,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3549,7 +3753,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib809x_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3577,6 +3781,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3586,7 +3792,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = dib9090_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3614,6 +3820,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3623,7 +3831,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = nim8096md_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3651,6 +3859,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3660,7 +3870,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = nim9090md_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3688,6 +3898,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3697,7 +3909,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = nim7090_tuner_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3725,6 +3937,8 @@ struct dvb_usb_device_properties dib0700_devices[] = { .num_adapters = 2, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3734,11 +3948,13 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = tfe7090pvr_tuner0_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x03), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -3748,7 +3964,7 @@ struct dvb_usb_device_properties dib0700_devices[] = { .tuner_attach = tfe7090pvr_tuner1_attach, DIB0700_DEFAULT_STREAMING_CONFIG(0x02), - + }}, .size_of_priv = sizeof(struct dib0700_adapter_state), }, @@ -3772,6 +3988,43 @@ struct dvb_usb_device_properties dib0700_devices[] = { RC_TYPE_NEC, .change_protocol = dib0700_change_protocol, }, + }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, + .num_adapters = 1, + .adapter = { + { + .num_frontends = 1, + .fe = {{ + .frontend_attach = pctv340e_frontend_attach, + .tuner_attach = xc4000_tuner_attach, + + DIB0700_DEFAULT_STREAMING_CONFIG(0x02), + }}, + .size_of_priv = sizeof(struct + dib0700_adapter_state), + }, + }, + + .num_device_descs = 2, + .devices = { + { "Pinnacle PCTV 340e HD Pro USB Stick", + { &dib0700_usb_id_table[76], NULL }, + { NULL }, + }, + { "Pinnacle PCTV Hybrid Stick Solo", + { &dib0700_usb_id_table[77], NULL }, + { NULL }, + }, + }, + .rc.core = { + .rc_interval = DEFAULT_RC_INTERVAL, + .rc_codes = RC_MAP_DIB0700_RC5_TABLE, + .module_name = "dib0700", + .rc_query = dib0700_rc_query_old_firmware, + .allowed_protos = RC_TYPE_RC5 | + RC_TYPE_RC6 | + RC_TYPE_NEC, + .change_protocol = dib0700_change_protocol, + }, }, }; diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 4c2a689..a76bbb2 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c @@ -23,7 +23,7 @@ int dibusb_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) if (adap->priv != NULL) { struct dibusb_state *st = adap->priv; if (st->ops.fifo_ctrl != NULL) - if (st->ops.fifo_ctrl(adap->fe,onoff)) { + if (st->ops.fifo_ctrl(adap->fe_adap[0].fe, onoff)) { err("error while controlling the fifo of the demod."); return -ENODEV; } @@ -37,7 +37,8 @@ int dibusb_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onof if (adap->priv != NULL) { struct dibusb_state *st = adap->priv; if (st->ops.pid_ctrl != NULL) - st->ops.pid_ctrl(adap->fe,index,pid,onoff); + st->ops.pid_ctrl(adap->fe_adap[0].fe, + index, pid, onoff); } return 0; } @@ -48,7 +49,7 @@ int dibusb_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) if (adap->priv != NULL) { struct dibusb_state *st = adap->priv; if (st->ops.pid_parse != NULL) - if (st->ops.pid_parse(adap->fe,onoff) < 0) + if (st->ops.pid_parse(adap->fe_adap[0].fe, onoff) < 0) err("could not handle pid_parser"); } return 0; @@ -254,8 +255,16 @@ int dibusb_dib3000mc_frontend_attach(struct dvb_usb_adapter *adap) msleep(1000); } - if ((adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000P_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL || - (adap->fe = dvb_attach(dib3000mc_attach, &adap->dev->i2c_adap, DEFAULT_DIB3000MC_I2C_ADDRESS, &mod3000p_dib3000p_config)) != NULL) { + adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, + &adap->dev->i2c_adap, + DEFAULT_DIB3000P_I2C_ADDRESS, + &mod3000p_dib3000p_config); + if ((adap->fe_adap[0].fe) == NULL) + adap->fe_adap[0].fe = dvb_attach(dib3000mc_attach, + &adap->dev->i2c_adap, + DEFAULT_DIB3000MC_I2C_ADDRESS, + &mod3000p_dib3000p_config); + if ((adap->fe_adap[0].fe) != NULL) { if (adap->priv != NULL) { struct dibusb_state *st = adap->priv; st->ops.pid_parse = dib3000mc_pid_parse; @@ -309,15 +318,15 @@ int dibusb_dib3000mc_tuner_attach(struct dvb_usb_adapter *adap) } } - tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe, 1); - if (dvb_attach(mt2060_attach, adap->fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) { + tun_i2c = dib3000mc_get_tuner_i2c_master(adap->fe_adap[0].fe, 1); + if (dvb_attach(mt2060_attach, adap->fe_adap[0].fe, tun_i2c, &stk3000p_mt2060_config, if1) == NULL) { /* not found - use panasonic pll parameters */ - if (dvb_attach(dvb_pll_attach, adap->fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL) + if (dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, tun_i2c, DVB_PLL_ENV57H1XD5) == NULL) return -ENOMEM; } else { st->mt2060_present = 1; /* set the correct parameters for the dib3000p */ - dib3000mc_set_config(adap->fe, &stk3000p_dib3000p_config); + dib3000mc_set_config(adap->fe_adap[0].fe, &stk3000p_dib3000p_config); } return 0; } diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 04d91bd..7270791 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -31,11 +31,12 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_adapter *adap) demod_cfg.demod_address = 0x8; - if ((adap->fe = dvb_attach(dib3000mb_attach, &demod_cfg, - &adap->dev->i2c_adap, &st->ops)) == NULL) + adap->fe_adap[0].fe = dvb_attach(dib3000mb_attach, &demod_cfg, + &adap->dev->i2c_adap, &st->ops); + if ((adap->fe_adap[0].fe) == NULL) return -ENODEV; - adap->fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl; + adap->fe_adap[0].fe->ops.i2c_gate_ctrl = dib3000mb_i2c_gate_ctrl; return 0; } @@ -46,7 +47,7 @@ static int dibusb_thomson_tuner_attach(struct dvb_usb_adapter *adap) st->tuner_addr = 0x61; - dvb_attach(dvb_pll_attach, adap->fe, 0x61, &adap->dev->i2c_adap, + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap, DVB_PLL_TUA6010XS); return 0; } @@ -57,7 +58,7 @@ static int dibusb_panasonic_tuner_attach(struct dvb_usb_adapter *adap) st->tuner_addr = 0x60; - dvb_attach(dvb_pll_attach, adap->fe, 0x60, &adap->dev->i2c_adap, + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, DVB_PLL_TDA665X); return 0; } @@ -78,16 +79,16 @@ static int dibusb_tuner_probe_and_attach(struct dvb_usb_adapter *adap) /* the Panasonic sits on I2C addrass 0x60, the Thomson on 0x61 */ msg[0].addr = msg[1].addr = st->tuner_addr = 0x60; - if (adap->fe->ops.i2c_gate_ctrl) - adap->fe->ops.i2c_gate_ctrl(adap->fe,1); + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); if (i2c_transfer(&adap->dev->i2c_adap, msg, 2) != 2) { err("tuner i2c write failed."); ret = -EREMOTEIO; } - if (adap->fe->ops.i2c_gate_ctrl) - adap->fe->ops.i2c_gate_ctrl(adap->fe,0); + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); if (b2[0] == 0xfe) { info("This device has the Thomson Cable onboard. Which is default."); @@ -185,6 +186,8 @@ static struct dvb_usb_device_properties dibusb1_1_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 16, @@ -205,6 +208,7 @@ static struct dvb_usb_device_properties dibusb1_1_properties = { } } }, + }}, .size_of_priv = sizeof(struct dibusb_state), } }, @@ -272,6 +276,8 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF | DVB_USB_ADAP_HAS_PID_FILTER, .pid_filter_count = 16, @@ -292,6 +298,7 @@ static struct dvb_usb_device_properties dibusb1_1_an2235_properties = { } } }, + }}, .size_of_priv = sizeof(struct dibusb_state), }, }, @@ -338,6 +345,8 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 16, @@ -358,6 +367,7 @@ static struct dvb_usb_device_properties dibusb2_0b_properties = { } } }, + }}, .size_of_priv = sizeof(struct dibusb_state), } }, @@ -398,6 +408,8 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 16, @@ -417,6 +429,7 @@ static struct dvb_usb_device_properties artec_t1_usb2_properties = { } } }, + }}, .size_of_priv = sizeof(struct dibusb_state), } }, diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c index c1d9094..9c165e2 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -57,6 +57,8 @@ static struct dvb_usb_device_properties dibusb_mc_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, .streaming_ctrl = dibusb2_0_streaming_ctrl, @@ -76,6 +78,7 @@ static struct dvb_usb_device_properties dibusb_mc_properties = { } } }, + }}, .size_of_priv = sizeof(struct dibusb_state), } }, diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f6344cd..f718411 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -137,11 +137,16 @@ static int digitv_frontend_attach(struct dvb_usb_adapter *adap) { struct digitv_state *st = adap->dev->priv; - if ((adap->fe = dvb_attach(mt352_attach, &digitv_mt352_config, &adap->dev->i2c_adap)) != NULL) { + adap->fe_adap[0].fe = dvb_attach(mt352_attach, &digitv_mt352_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) { st->is_nxt6000 = 0; return 0; } - if ((adap->fe = dvb_attach(nxt6000_attach, &digitv_nxt6000_config, &adap->dev->i2c_adap)) != NULL) { + adap->fe_adap[0].fe = dvb_attach(nxt6000_attach, + &digitv_nxt6000_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) != NULL) { st->is_nxt6000 = 1; return 0; } @@ -152,11 +157,11 @@ static int digitv_tuner_attach(struct dvb_usb_adapter *adap) { struct digitv_state *st = adap->dev->priv; - if (!dvb_attach(dvb_pll_attach, adap->fe, 0x60, NULL, DVB_PLL_TDED4)) + if (!dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, NULL, DVB_PLL_TDED4)) return -ENODEV; if (st->is_nxt6000) - adap->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; + adap->fe_adap[0].fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params; return 0; } @@ -292,6 +297,8 @@ static struct dvb_usb_device_properties digitv_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = digitv_frontend_attach, .tuner_attach = digitv_tuner_attach, @@ -306,6 +313,7 @@ static struct dvb_usb_device_properties digitv_properties = { } } }, + }}, } }, .identify_state = digitv_identify_state, diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index ecd86ec..106dfd5 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -90,7 +90,7 @@ static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap) { - adap->fe = dtt200u_fe_attach(adap->dev); + adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev); return 0; } @@ -140,6 +140,8 @@ static struct dvb_usb_device_properties dtt200u_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, .pid_filter_count = 15, @@ -157,6 +159,7 @@ static struct dvb_usb_device_properties dtt200u_properties = { } } }, + }}, } }, .power_ctrl = dtt200u_power_ctrl, @@ -187,6 +190,8 @@ static struct dvb_usb_device_properties wt220u_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, .pid_filter_count = 15, @@ -204,6 +209,7 @@ static struct dvb_usb_device_properties wt220u_properties = { } } }, + }}, } }, .power_ctrl = dtt200u_power_ctrl, @@ -234,6 +240,8 @@ static struct dvb_usb_device_properties wt220u_fc_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, .pid_filter_count = 15, @@ -251,6 +259,7 @@ static struct dvb_usb_device_properties wt220u_fc_properties = { } } }, + }}, } }, .power_ctrl = dtt200u_power_ctrl, @@ -281,6 +290,8 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, .pid_filter_count = 15, @@ -298,6 +309,7 @@ static struct dvb_usb_device_properties wt220u_zl0353_properties = { } } }, + }}, } }, .power_ctrl = dtt200u_power_ctrl, diff --git a/drivers/media/dvb/dvb-usb/dtv5100.c b/drivers/media/dvb/dvb-usb/dtv5100.c index 078ce92..7373132 100644 --- a/drivers/media/dvb/dvb-usb/dtv5100.c +++ b/drivers/media/dvb/dvb-usb/dtv5100.c @@ -115,13 +115,13 @@ static struct zl10353_config dtv5100_zl10353_config = { static int dtv5100_frontend_attach(struct dvb_usb_adapter *adap) { - adap->fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config, + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &dtv5100_zl10353_config, &adap->dev->i2c_adap); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -EIO; /* disable i2c gate, or it won't work... is this safe? */ - adap->fe->ops.i2c_gate_ctrl = NULL; + adap->fe_adap[0].fe->ops.i2c_gate_ctrl = NULL; return 0; } @@ -133,7 +133,7 @@ static struct qt1010_config dtv5100_qt1010_config = { static int dtv5100_tuner_attach(struct dvb_usb_adapter *adap) { return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, + adap->fe_adap[0].fe, &adap->dev->i2c_adap, &dtv5100_qt1010_config) == NULL ? -ENODEV : 0; } @@ -180,6 +180,8 @@ static struct dvb_usb_device_properties dtv5100_properties = { .num_adapters = 1, .adapter = {{ + .num_frontends = 1, + .fe = {{ .frontend_attach = dtv5100_frontend_attach, .tuner_attach = dtv5100_tuner_attach, @@ -193,6 +195,7 @@ static struct dvb_usb_device_properties dtv5100_properties = { } } }, + }}, } }, .i2c_algo = &dtv5100_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index b3cb626..ba4a751 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c @@ -17,15 +17,20 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) if (adap == NULL) return -ENODEV; + if ((adap->active_fe < 0) || + (adap->active_fe >= adap->num_frontends_initialized)) { + return -EINVAL; + } + newfeedcount = adap->feedcount + (onoff ? 1 : -1); /* stop feed before setting a new pid if there will be no pid anymore */ if (newfeedcount == 0) { deb_ts("stop feeding\n"); - usb_urb_kill(&adap->stream); + usb_urb_kill(&adap->fe_adap[adap->active_fe].stream); - if (adap->props.streaming_ctrl != NULL) { - ret = adap->props.streaming_ctrl(adap, 0); + if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) { + ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 0); if (ret < 0) { err("error while stopping stream."); return ret; @@ -36,36 +41,37 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) adap->feedcount = newfeedcount; /* activate the pid on the device specific pid_filter */ - deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n",adap->pid_filtering ? - "yes" : "no", dvbdmxfeed->pid,dvbdmxfeed->pid,dvbdmxfeed->index,onoff ? - "on" : "off"); - if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER && - adap->pid_filtering && - adap->props.pid_filter != NULL) - adap->props.pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid,onoff); + deb_ts("setting pid (%s): %5d %04x at index %d '%s'\n", + adap->fe_adap[adap->active_fe].pid_filtering ? + "yes" : "no", dvbdmxfeed->pid, dvbdmxfeed->pid, + dvbdmxfeed->index, onoff ? "on" : "off"); + if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER && + adap->fe_adap[adap->active_fe].pid_filtering && + adap->props.fe[adap->active_fe].pid_filter != NULL) + adap->props.fe[adap->active_fe].pid_filter(adap, dvbdmxfeed->index, dvbdmxfeed->pid, onoff); /* start the feed if this was the first feed and there is still a feed * for reception. */ if (adap->feedcount == onoff && adap->feedcount > 0) { deb_ts("submitting all URBs\n"); - usb_urb_submit(&adap->stream); + usb_urb_submit(&adap->fe_adap[adap->active_fe].stream); deb_ts("controlling pid parser\n"); - if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER && - adap->props.caps & + if (adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_HAS_PID_FILTER && + adap->props.fe[adap->active_fe].caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF && - adap->props.pid_filter_ctrl != NULL) { - ret = adap->props.pid_filter_ctrl(adap, - adap->pid_filtering); + adap->props.fe[adap->active_fe].pid_filter_ctrl != NULL) { + ret = adap->props.fe[adap->active_fe].pid_filter_ctrl(adap, + adap->fe_adap[adap->active_fe].pid_filtering); if (ret < 0) { err("could not handle pid_parser"); return ret; } } deb_ts("start feeding\n"); - if (adap->props.streaming_ctrl != NULL) { - ret = adap->props.streaming_ctrl(adap, 1); + if (adap->props.fe[adap->active_fe].streaming_ctrl != NULL) { + ret = adap->props.fe[adap->active_fe].streaming_ctrl(adap, 1); if (ret < 0) { err("error while enabling fifo."); return ret; @@ -90,6 +96,7 @@ static int dvb_usb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) { + int i; int ret = dvb_register_adapter(&adap->dvb_adap, adap->dev->desc->name, adap->dev->owner, &adap->dev->udev->dev, adapter_nums); @@ -112,7 +119,12 @@ int dvb_usb_adapter_dvb_init(struct dvb_usb_adapter *adap, short *adapter_nums) adap->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; adap->demux.priv = adap; - adap->demux.feednum = adap->demux.filternum = adap->max_feed_count; + adap->demux.filternum = 0; + for (i = 0; i < adap->props.num_frontends; i++) { + if (adap->demux.filternum < adap->fe_adap[i].max_feed_count) + adap->demux.filternum = adap->fe_adap[i].max_feed_count; + } + adap->demux.feednum = adap->demux.filternum; adap->demux.start_feed = dvb_usb_start_feed; adap->demux.stop_feed = dvb_usb_stop_feed; adap->demux.write_to_decoder = NULL; @@ -156,14 +168,33 @@ int dvb_usb_adapter_dvb_exit(struct dvb_usb_adapter *adap) return 0; } +static int dvb_usb_set_active_fe(struct dvb_frontend *fe, int onoff) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + + int ret = (adap->props.frontend_ctrl) ? + adap->props.frontend_ctrl(fe, onoff) : 0; + + if (ret < 0) { + err("frontend_ctrl request failed"); + return ret; + } + if (onoff) + adap->active_fe = fe->id; + + return 0; +} + static int dvb_usb_fe_wakeup(struct dvb_frontend *fe) { struct dvb_usb_adapter *adap = fe->dvb->priv; dvb_usb_device_power_ctrl(adap->dev, 1); - if (adap->fe_init) - adap->fe_init(fe); + dvb_usb_set_active_fe(fe, 1); + + if (adap->fe_adap[fe->id].fe_init) + adap->fe_adap[fe->id].fe_init(fe); return 0; } @@ -172,45 +203,81 @@ static int dvb_usb_fe_sleep(struct dvb_frontend *fe) { struct dvb_usb_adapter *adap = fe->dvb->priv; - if (adap->fe_sleep) - adap->fe_sleep(fe); + if (adap->fe_adap[fe->id].fe_sleep) + adap->fe_adap[fe->id].fe_sleep(fe); + + dvb_usb_set_active_fe(fe, 0); return dvb_usb_device_power_ctrl(adap->dev, 0); } int dvb_usb_adapter_frontend_init(struct dvb_usb_adapter *adap) { - if (adap->props.frontend_attach == NULL) { - err("strange: '%s' #%d doesn't want to attach a frontend.",adap->dev->desc->name, adap->id); - return 0; - } + int ret, i; - /* re-assign sleep and wakeup functions */ - if (adap->props.frontend_attach(adap) == 0 && adap->fe != NULL) { - adap->fe_init = adap->fe->ops.init; adap->fe->ops.init = dvb_usb_fe_wakeup; - adap->fe_sleep = adap->fe->ops.sleep; adap->fe->ops.sleep = dvb_usb_fe_sleep; + /* register all given adapter frontends */ + for (i = 0; i < adap->props.num_frontends; i++) { - if (dvb_register_frontend(&adap->dvb_adap, adap->fe)) { - err("Frontend registration failed."); - dvb_frontend_detach(adap->fe); - adap->fe = NULL; - return -ENODEV; + if (adap->props.fe[i].frontend_attach == NULL) { + err("strange: '%s' #%d,%d " + "doesn't want to attach a frontend.", + adap->dev->desc->name, adap->id, i); + + return 0; + } + + ret = adap->props.fe[i].frontend_attach(adap); + if (ret || adap->fe_adap[i].fe == NULL) { + /* only print error when there is no FE at all */ + if (i == 0) + err("no frontend was attached by '%s'", + adap->dev->desc->name); + + return 0; + } + + adap->fe_adap[i].fe->id = i; + + /* re-assign sleep and wakeup functions */ + adap->fe_adap[i].fe_init = adap->fe_adap[i].fe->ops.init; + adap->fe_adap[i].fe->ops.init = dvb_usb_fe_wakeup; + adap->fe_adap[i].fe_sleep = adap->fe_adap[i].fe->ops.sleep; + adap->fe_adap[i].fe->ops.sleep = dvb_usb_fe_sleep; + + if (dvb_register_frontend(&adap->dvb_adap, adap->fe_adap[i].fe)) { + err("Frontend %d registration failed.", i); + dvb_frontend_detach(adap->fe_adap[i].fe); + adap->fe_adap[i].fe = NULL; + /* In error case, do not try register more FEs, + * still leaving already registered FEs alive. */ + if (i == 0) + return -ENODEV; + else + return 0; } /* only attach the tuner if the demod is there */ - if (adap->props.tuner_attach != NULL) - adap->props.tuner_attach(adap); - } else - err("no frontend was attached by '%s'",adap->dev->desc->name); + if (adap->props.fe[i].tuner_attach != NULL) + adap->props.fe[i].tuner_attach(adap); + + adap->num_frontends_initialized++; + } return 0; } int dvb_usb_adapter_frontend_exit(struct dvb_usb_adapter *adap) { - if (adap->fe != NULL) { - dvb_unregister_frontend(adap->fe); - dvb_frontend_detach(adap->fe); + int i = adap->num_frontends_initialized - 1; + + /* unregister all given adapter frontends */ + for (; i >= 0; i--) { + if (adap->fe_adap[i].fe != NULL) { + dvb_unregister_frontend(adap->fe_adap[i].fe); + dvb_frontend_detach(adap->fe_adap[i].fe); + } } + adap->num_frontends_initialized = 0; + return 0; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 21b1549..2d08c9b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -37,6 +37,7 @@ #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 #define USB_VID_INTEL 0x8086 +#define USB_VID_ITETECH 0x048d #define USB_VID_KWORLD 0xeb2a #define USB_VID_KWORLD_2 0x1b80 #define USB_VID_KYE 0x0458 @@ -126,6 +127,7 @@ #define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 #define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 #define USB_PID_INTEL_CE9500 0x9500 +#define USB_PID_ITETECH_IT9135 0x9135 #define USB_PID_KWORLD_399U 0xe399 #define USB_PID_KWORLD_399U_2 0xe400 #define USB_PID_KWORLD_395U 0xe396 @@ -136,6 +138,7 @@ #define USB_PID_KWORLD_PC160_2T 0xc160 #define USB_PID_KWORLD_PC160_T 0xc161 #define USB_PID_KWORLD_UB383_T 0xe383 +#define USB_PID_KWORLD_UB499_2T_T09 0xe409 #define USB_PID_KWORLD_VSTREAM_COLD 0x17de #define USB_PID_KWORLD_VSTREAM_WARM 0x17df #define USB_PID_TERRATEC_CINERGY_T_USB_XE 0x0055 @@ -230,6 +233,8 @@ #define USB_PID_PINNACLE_PCTV310E 0x3211 #define USB_PID_PINNACLE_PCTV801E 0x023a #define USB_PID_PINNACLE_PCTV801E_SE 0x023b +#define USB_PID_PINNACLE_PCTV340E 0x023d +#define USB_PID_PINNACLE_PCTV340E_SE 0x023e #define USB_PID_PINNACLE_PCTV73A 0x0243 #define USB_PID_PINNACLE_PCTV73ESE 0x0245 #define USB_PID_PINNACLE_PCTV74E 0x0246 @@ -238,6 +243,9 @@ #define USB_PID_PCTV_200E 0x020e #define USB_PID_PCTV_400E 0x020f #define USB_PID_PCTV_450E 0x0222 +#define USB_PID_PCTV_452E 0x021f +#define USB_PID_TECHNOTREND_CONNECT_S2_3600 0x3007 +#define USB_PID_TECHNOTREND_CONNECT_S2_3650_CI 0x300a #define USB_PID_NEBULA_DIGITV 0x0201 #define USB_PID_DVICO_BLUEBIRD_LGDT 0xd820 #define USB_PID_DVICO_BLUEBIRD_LG064F_COLD 0xd500 @@ -313,6 +321,7 @@ #define USB_PID_FRIIO_WHITE 0x0001 #define USB_PID_TVWAY_PLUS 0x0002 #define USB_PID_SVEON_STV20 0xe39d +#define USB_PID_SVEON_STV22 0xe401 #define USB_PID_AZUREWAVE_AZ6027 0x3275 #define USB_PID_TERRATEC_DVBS2CI_V1 0x10a4 #define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 2e3ea0f..169196e 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -29,7 +29,7 @@ MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) { struct dvb_usb_adapter *adap; - int ret, n; + int ret, n, o; for (n = 0; n < d->props.num_adapters; n++) { adap = &d->adapter[n]; @@ -38,31 +38,42 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties)); + for (o = 0; o < adap->props.num_frontends; o++) { + struct dvb_usb_adapter_fe_properties *props = &adap->props.fe[o]; /* speed - when running at FULL speed we need a HW PID filter */ - if (d->udev->speed == USB_SPEED_FULL && !(adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER)) { + if (d->udev->speed == USB_SPEED_FULL && !(props->caps & DVB_USB_ADAP_HAS_PID_FILTER)) { err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)"); return -ENODEV; } - if ((d->udev->speed == USB_SPEED_FULL && adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) || - (adap->props.caps & DVB_USB_ADAP_NEED_PID_FILTERING)) { - info("will use the device's hardware PID filter (table count: %d).", adap->props.pid_filter_count); - adap->pid_filtering = 1; - adap->max_feed_count = adap->props.pid_filter_count; + if ((d->udev->speed == USB_SPEED_FULL && props->caps & DVB_USB_ADAP_HAS_PID_FILTER) || + (props->caps & DVB_USB_ADAP_NEED_PID_FILTERING)) { + info("will use the device's hardware PID filter (table count: %d).", props->pid_filter_count); + adap->fe_adap[o].pid_filtering = 1; + adap->fe_adap[o].max_feed_count = props->pid_filter_count; } else { info("will pass the complete MPEG2 transport stream to the software demuxer."); - adap->pid_filtering = 0; - adap->max_feed_count = 255; + adap->fe_adap[o].pid_filtering = 0; + adap->fe_adap[o].max_feed_count = 255; } - if (!adap->pid_filtering && + if (!adap->fe_adap[o].pid_filtering && dvb_usb_force_pid_filter_usage && - adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) { + props->caps & DVB_USB_ADAP_HAS_PID_FILTER) { info("pid filter enabled by module option."); - adap->pid_filtering = 1; - adap->max_feed_count = adap->props.pid_filter_count; + adap->fe_adap[o].pid_filtering = 1; + adap->fe_adap[o].max_feed_count = props->pid_filter_count; } + if (props->size_of_priv > 0) { + adap->fe_adap[o].priv = kzalloc(props->size_of_priv, GFP_KERNEL); + if (adap->fe_adap[o].priv == NULL) { + err("no memory for priv for adapter %d fe %d.", n, o); + return -ENOMEM; + } + } + } + if (adap->props.size_of_priv > 0) { adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL); if (adap->priv == NULL) { @@ -77,6 +88,10 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs) return ret; } + /* use exclusive FE lock if there is multiple shared FEs */ + if (adap->fe_adap[1].fe) + adap->dvb_adap.mfe_shared = 1; + d->num_adapters_initialized++; d->state |= DVB_USB_STATE_DVB; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c index bb46ba6..53a5c30 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-urb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-urb.c @@ -82,16 +82,28 @@ static void dvb_usb_data_complete_204(struct usb_data_stream *stream, u8 *buffer int dvb_usb_adapter_stream_init(struct dvb_usb_adapter *adap) { - adap->stream.udev = adap->dev->udev; - if (adap->props.caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS) - adap->stream.complete = dvb_usb_data_complete_204; - else - adap->stream.complete = dvb_usb_data_complete; - adap->stream.user_priv = adap; - return usb_urb_init(&adap->stream, &adap->props.stream); + int i, ret = 0; + for (i = 0; i < adap->props.num_frontends; i++) { + + adap->fe_adap[i].stream.udev = adap->dev->udev; + if (adap->props.fe[i].caps & DVB_USB_ADAP_RECEIVES_204_BYTE_TS) + adap->fe_adap[i].stream.complete = + dvb_usb_data_complete_204; + else + adap->fe_adap[i].stream.complete = dvb_usb_data_complete; + adap->fe_adap[i].stream.user_priv = adap; + ret = usb_urb_init(&adap->fe_adap[i].stream, + &adap->props.fe[i].stream); + if (ret < 0) + break; + } + return ret; } int dvb_usb_adapter_stream_exit(struct dvb_usb_adapter *adap) { - return usb_urb_exit(&adap->stream); + int i; + for (i = 0; i < adap->props.num_frontends; i++) + usb_urb_exit(&adap->fe_adap[i].stream); + return 0; } diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index 76a8096..6d7d13f 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -85,7 +85,7 @@ static inline u8 rc5_data(struct rc_map_table *key) return key->scancode & 0xff; } -static inline u8 rc5_scan(struct rc_map_table *key) +static inline u16 rc5_scan(struct rc_map_table *key) { return key->scancode & 0xffff; } @@ -124,6 +124,8 @@ struct usb_data_stream_properties { * @caps: capabilities of the DVB USB device. * @pid_filter_count: number of PID filter position in the optional hardware * PID-filter. + * @num_frontends: number of frontends of the DVB USB adapter. + * @frontend_ctrl: called to power on/off active frontend. * @streaming_ctrl: called to start and stop the MPEG2-TS streaming of the * device (not URB submitting/killing). * @pid_filter_ctrl: called to en/disable the PID filter, if any. @@ -134,7 +136,7 @@ struct usb_data_stream_properties { * pll_desc and pll_init_buf of struct dvb_usb_device). * @stream: configuration of the USB streaming */ -struct dvb_usb_adapter_properties { +struct dvb_usb_adapter_fe_properties { #define DVB_USB_ADAP_HAS_PID_FILTER 0x01 #define DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF 0x02 #define DVB_USB_ADAP_NEED_PID_FILTERING 0x04 @@ -152,9 +154,18 @@ struct dvb_usb_adapter_properties { struct usb_data_stream_properties stream; int size_of_priv; +}; + +#define MAX_NO_OF_FE_PER_ADAP 2 +struct dvb_usb_adapter_properties { + int size_of_priv; + int (*frontend_ctrl) (struct dvb_frontend *, int); int (*fe_ioctl_override) (struct dvb_frontend *, unsigned int, void *, unsigned int); + + int num_frontends; + struct dvb_usb_adapter_fe_properties fe[MAX_NO_OF_FE_PER_ADAP]; }; /** @@ -345,6 +356,20 @@ struct usb_data_stream { * * @stream: the usb data stream. */ +struct dvb_usb_fe_adapter { + struct dvb_frontend *fe; + + int (*fe_init) (struct dvb_frontend *); + int (*fe_sleep) (struct dvb_frontend *); + + struct usb_data_stream stream; + + int pid_filtering; + int max_feed_count; + + void *priv; +}; + struct dvb_usb_adapter { struct dvb_usb_device *dev; struct dvb_usb_adapter_properties props; @@ -356,20 +381,16 @@ struct dvb_usb_adapter { u8 id; int feedcount; - int pid_filtering; /* dvb */ struct dvb_adapter dvb_adap; struct dmxdev dmxdev; struct dvb_demux demux; struct dvb_net dvb_net; - struct dvb_frontend *fe; - int max_feed_count; - - int (*fe_init) (struct dvb_frontend *); - int (*fe_sleep) (struct dvb_frontend *); - struct usb_data_stream stream; + struct dvb_usb_fe_adapter fe_adap[MAX_NO_OF_FE_PER_ADAP]; + int active_fe; + int num_frontends_initialized; void *priv; }; diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c index 058b231..f103ec1 100644 --- a/drivers/media/dvb/dvb-usb/dw2102.c +++ b/drivers/media/dvb/dvb-usb/dw2102.c @@ -992,18 +992,18 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) struct dvb_tuner_ops *tuner_ops = NULL; if (demod_probe & 4) { - d->fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, + d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104a_stv0900_config, &d->dev->i2c_adap, 0); - if (d->fe != NULL) { - if (dvb_attach(stb6100_attach, d->fe, + if (d->fe_adap[0].fe != NULL) { + if (dvb_attach(stb6100_attach, d->fe_adap[0].fe, &dw2104a_stb6100_config, &d->dev->i2c_adap)) { - tuner_ops = &d->fe->ops.tuner_ops; + tuner_ops = &d->fe_adap[0].fe->ops.tuner_ops; tuner_ops->set_frequency = stb6100_set_freq; tuner_ops->get_frequency = stb6100_get_freq; tuner_ops->set_bandwidth = stb6100_set_bandw; tuner_ops->get_bandwidth = stb6100_get_bandw; - d->fe->ops.set_voltage = dw210x_set_voltage; + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached STV0900+STB6100!\n"); return 0; } @@ -1011,13 +1011,13 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) } if (demod_probe & 2) { - d->fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, + d->fe_adap[0].fe = dvb_attach(stv0900_attach, &dw2104_stv0900_config, &d->dev->i2c_adap, 0); - if (d->fe != NULL) { - if (dvb_attach(stv6110_attach, d->fe, + if (d->fe_adap[0].fe != NULL) { + if (dvb_attach(stv6110_attach, d->fe_adap[0].fe, &dw2104_stv6110_config, &d->dev->i2c_adap)) { - d->fe->ops.set_voltage = dw210x_set_voltage; + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached STV0900+STV6110A!\n"); return 0; } @@ -1025,19 +1025,19 @@ static int dw2104_frontend_attach(struct dvb_usb_adapter *d) } if (demod_probe & 1) { - d->fe = dvb_attach(cx24116_attach, &dw2104_config, + d->fe_adap[0].fe = dvb_attach(cx24116_attach, &dw2104_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; + if (d->fe_adap[0].fe != NULL) { + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached cx24116!\n"); return 0; } } - d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, + d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; + if (d->fe_adap[0].fe != NULL) { + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached DS3000!\n"); return 0; } @@ -1053,22 +1053,22 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) { if (dw2102_properties.i2c_algo == &dw2102_serit_i2c_algo) { /*dw2102_properties.adapter->tuner_attach = NULL;*/ - d->fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config, + d->fe_adap[0].fe = dvb_attach(si21xx_attach, &serit_sp1511lhb_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; + if (d->fe_adap[0].fe != NULL) { + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached si21xx!\n"); return 0; } } if (dw2102_properties.i2c_algo == &dw2102_earda_i2c_algo) { - d->fe = dvb_attach(stv0288_attach, &earda_config, + d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - if (dvb_attach(stb6000_attach, d->fe, 0x61, + if (d->fe_adap[0].fe != NULL) { + if (dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap)) { - d->fe->ops.set_voltage = dw210x_set_voltage; + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached stv0288!\n"); return 0; } @@ -1077,10 +1077,10 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) if (dw2102_properties.i2c_algo == &dw2102_i2c_algo) { /*dw2102_properties.adapter->tuner_attach = dw2102_tuner_attach;*/ - d->fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, + d->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194a_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - d->fe->ops.set_voltage = dw210x_set_voltage; + if (d->fe_adap[0].fe != NULL) { + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached stv0299!\n"); return 0; } @@ -1090,9 +1090,9 @@ static int dw2102_frontend_attach(struct dvb_usb_adapter *d) static int dw3101_frontend_attach(struct dvb_usb_adapter *d) { - d->fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, + d->fe_adap[0].fe = dvb_attach(tda10023_attach, &dw3101_tda10023_config, &d->dev->i2c_adap, 0x48); - if (d->fe != NULL) { + if (d->fe_adap[0].fe != NULL) { info("Attached tda10023!\n"); return 0; } @@ -1101,12 +1101,12 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d) static int zl100313_frontend_attach(struct dvb_usb_adapter *d) { - d->fe = dvb_attach(mt312_attach, &zl313_config, + d->fe_adap[0].fe = dvb_attach(mt312_attach, &zl313_config, &d->dev->i2c_adap); - if (d->fe != NULL) { - if (dvb_attach(zl10039_attach, d->fe, 0x60, + if (d->fe_adap[0].fe != NULL) { + if (dvb_attach(zl10039_attach, d->fe_adap[0].fe, 0x60, &d->dev->i2c_adap)) { - d->fe->ops.set_voltage = dw210x_set_voltage; + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; info("Attached zl100313+zl10039!\n"); return 0; } @@ -1119,16 +1119,16 @@ static int stv0288_frontend_attach(struct dvb_usb_adapter *d) { u8 obuf[] = {7, 1}; - d->fe = dvb_attach(stv0288_attach, &earda_config, + d->fe_adap[0].fe = dvb_attach(stv0288_attach, &earda_config, &d->dev->i2c_adap); - if (d->fe == NULL) + if (d->fe_adap[0].fe == NULL) return -EIO; - if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap)) + if (NULL == dvb_attach(stb6000_attach, d->fe_adap[0].fe, 0x61, &d->dev->i2c_adap)) return -EIO; - d->fe->ops.set_voltage = dw210x_set_voltage; + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); @@ -1143,14 +1143,14 @@ static int ds3000_frontend_attach(struct dvb_usb_adapter *d) struct s6x0_state *st = (struct s6x0_state *)d->dev->priv; u8 obuf[] = {7, 1}; - d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, + d->fe_adap[0].fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, &d->dev->i2c_adap); - if (d->fe == NULL) + if (d->fe_adap[0].fe == NULL) return -EIO; - st->old_set_voltage = d->fe->ops.set_voltage; - d->fe->ops.set_voltage = s660_set_voltage; + st->old_set_voltage = d->fe_adap[0].fe->ops.set_voltage; + d->fe_adap[0].fe->ops.set_voltage = s660_set_voltage; dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); @@ -1163,12 +1163,12 @@ static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) { u8 obuf[] = {7, 1}; - d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, + d->fe_adap[0].fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, &d->dev->i2c_adap, 0); - if (d->fe == NULL) + if (d->fe_adap[0].fe == NULL) return -EIO; - d->fe->ops.set_voltage = dw210x_set_voltage; + d->fe_adap[0].fe->ops.set_voltage = dw210x_set_voltage; dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG); @@ -1204,9 +1204,9 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d) if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0) err("command 0x51 transfer failed."); - d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, + d->fe_adap[0].fe = dvb_attach(ds3000_attach, &su3000_ds3000_config, &d->dev->i2c_adap); - if (d->fe == NULL) + if (d->fe_adap[0].fe == NULL) return -EIO; info("Attached DS3000!\n"); @@ -1216,14 +1216,14 @@ static int su3000_frontend_attach(struct dvb_usb_adapter *d) static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(dvb_pll_attach, adap->fe, 0x60, + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, DVB_PLL_OPERA1); return 0; } static int dw3101_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(dvb_pll_attach, adap->fe, 0x60, + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, DVB_PLL_TUA6034); return 0; @@ -1535,7 +1535,7 @@ static int dw2102_load_firmware(struct usb_device *dev, DW210X_READ_MSG); if ((reset16[0] == 0xa1) || (reset16[0] == 0x80)) { dw2102_properties.i2c_algo = &dw2102_i2c_algo; - dw2102_properties.adapter->tuner_attach = &dw2102_tuner_attach; + dw2102_properties.adapter->fe[0].tuner_attach = &dw2102_tuner_attach; break; } else { /* check STV0288 frontend */ @@ -1591,6 +1591,8 @@ static struct dvb_usb_device_properties dw2102_properties = { .read_mac_address = dw210x_read_mac_address, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = dw2102_frontend_attach, .stream = { .type = USB_BULK, @@ -1602,6 +1604,7 @@ static struct dvb_usb_device_properties dw2102_properties = { } } }, + }}, } }, .num_device_descs = 3, @@ -1642,6 +1645,8 @@ static struct dvb_usb_device_properties dw2104_properties = { .read_mac_address = dw210x_read_mac_address, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = dw2104_frontend_attach, .stream = { .type = USB_BULK, @@ -1653,6 +1658,7 @@ static struct dvb_usb_device_properties dw2104_properties = { } } }, + }}, } }, .num_device_descs = 2, @@ -1689,6 +1695,8 @@ static struct dvb_usb_device_properties dw3101_properties = { .read_mac_address = dw210x_read_mac_address, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = dw3101_frontend_attach, .tuner_attach = dw3101_tuner_attach, .stream = { @@ -1701,6 +1709,7 @@ static struct dvb_usb_device_properties dw3101_properties = { } } }, + }}, } }, .num_device_descs = 1, @@ -1733,6 +1742,8 @@ static struct dvb_usb_device_properties s6x0_properties = { .read_mac_address = s6x0_read_mac_address, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = zl100313_frontend_attach, .stream = { .type = USB_BULK, @@ -1744,6 +1755,7 @@ static struct dvb_usb_device_properties s6x0_properties = { } } }, + }}, } }, .num_device_descs = 1, @@ -1810,6 +1822,8 @@ static struct dvb_usb_device_properties su3000_properties = { .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = su3000_streaming_ctrl, .frontend_attach = su3000_frontend_attach, .stream = { @@ -1822,6 +1836,7 @@ static struct dvb_usb_device_properties su3000_properties = { } } } + }}, } }, .num_device_descs = 3, @@ -1855,7 +1870,7 @@ static int dw2102_probe(struct usb_interface *intf, p1100->devices[0] = d1100; p1100->rc.legacy.rc_map_table = rc_map_tbs_table; p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); - p1100->adapter->frontend_attach = stv0288_frontend_attach; + p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!s660) { @@ -1869,7 +1884,7 @@ static int dw2102_probe(struct usb_interface *intf, s660->devices[0] = d660; s660->devices[1] = d480_1; s660->devices[2] = d480_2; - s660->adapter->frontend_attach = ds3000_frontend_attach; + s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); if (!p7500) { @@ -1883,7 +1898,7 @@ static int dw2102_probe(struct usb_interface *intf, p7500->devices[0] = d7500; p7500->rc.legacy.rc_map_table = rc_map_tbs_table; p7500->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table); - p7500->adapter->frontend_attach = prof_7500_frontend_attach; + p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach; if (0 == dvb_usb_device_init(intf, &dw2102_properties, THIS_MODULE, NULL, adapter_nr) || diff --git a/drivers/media/dvb/dvb-usb/ec168.c b/drivers/media/dvb/dvb-usb/ec168.c index 1ba3e5d..78442fe 100644 --- a/drivers/media/dvb/dvb-usb/ec168.c +++ b/drivers/media/dvb/dvb-usb/ec168.c @@ -200,9 +200,9 @@ static struct ec100_config ec168_ec100_config = { static int ec168_ec100_frontend_attach(struct dvb_usb_adapter *adap) { deb_info("%s:\n", __func__); - adap->fe = dvb_attach(ec100_attach, &ec168_ec100_config, + adap->fe_adap[0].fe = dvb_attach(ec100_attach, &ec168_ec100_config, &adap->dev->i2c_adap); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -ENODEV; return 0; @@ -228,7 +228,7 @@ static struct mxl5005s_config ec168_mxl5003s_config = { static int ec168_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap) { deb_info("%s:\n", __func__); - return dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap, + return dvb_attach(mxl5005s_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &ec168_mxl5003s_config) == NULL ? -ENODEV : 0; } @@ -382,6 +382,8 @@ static struct dvb_usb_device_properties ec168_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = ec168_streaming_ctrl, .frontend_attach = ec168_ec100_frontend_attach, .tuner_attach = ec168_mxl5003s_tuner_attach, @@ -395,6 +397,7 @@ static struct dvb_usb_device_properties ec168_properties = { } } }, + }}, } }, diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c index 76159ae..b092dc2 100644 --- a/drivers/media/dvb/dvb-usb/friio.c +++ b/drivers/media/dvb/dvb-usb/friio.c @@ -403,8 +403,8 @@ static int friio_frontend_attach(struct dvb_usb_adapter *adap) if (friio_initialize(adap->dev) < 0) return -EIO; - adap->fe = jdvbt90502_attach(adap->dev); - if (adap->fe == NULL) + adap->fe_adap[0].fe = jdvbt90502_attach(adap->dev); + if (adap->fe_adap[0].fe == NULL) return -EIO; return 0; @@ -473,6 +473,8 @@ static struct dvb_usb_device_properties friio_properties = { /* caps:0 => no pid filter, 188B TS packet */ /* GL861 has a HW pid filter, but no info available. */ { + .num_frontends = 1, + .fe = {{ .caps = 0, .frontend_attach = friio_frontend_attach, @@ -490,6 +492,7 @@ static struct dvb_usb_device_properties friio_properties = { } } }, + }}, } }, .i2c_algo = &gl861_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/gl861.c b/drivers/media/dvb/dvb-usb/gl861.c index 6f596ed..63681df 100644 --- a/drivers/media/dvb/dvb-usb/gl861.c +++ b/drivers/media/dvb/dvb-usb/gl861.c @@ -103,9 +103,9 @@ static struct zl10353_config gl861_zl10353_config = { static int gl861_frontend_attach(struct dvb_usb_adapter *adap) { - adap->fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, + adap->fe_adap[0].fe = dvb_attach(zl10353_attach, &gl861_zl10353_config, &adap->dev->i2c_adap); - if (adap->fe == NULL) + if (adap->fe_adap[0].fe == NULL) return -EIO; return 0; @@ -118,7 +118,7 @@ static struct qt1010_config gl861_qt1010_config = { static int gl861_tuner_attach(struct dvb_usb_adapter *adap) { return dvb_attach(qt1010_attach, - adap->fe, &adap->dev->i2c_adap, + adap->fe_adap[0].fe, &adap->dev->i2c_adap, &gl861_qt1010_config) == NULL ? -ENODEV : 0; } @@ -167,6 +167,8 @@ static struct dvb_usb_device_properties gl861_properties = { .num_adapters = 1, .adapter = {{ + .num_frontends = 1, + .fe = {{ .frontend_attach = gl861_frontend_attach, .tuner_attach = gl861_tuner_attach, @@ -181,6 +183,7 @@ static struct dvb_usb_device_properties gl861_properties = { } } }, + }}, } }, .i2c_algo = &gl861_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c index 60d11e5..5426267 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c +++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c @@ -144,19 +144,25 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, cmd[6] = (freq >> 16) & 0xff; cmd[7] = (freq >> 24) & 0xff; + /* backwards compatibility: DVB-S + 8-PSK were used for Turbo-FEC */ + if (c->delivery_system == SYS_DVBS && c->modulation == PSK_8) + c->delivery_system = SYS_TURBO; + switch (c->delivery_system) { case SYS_DVBS: - /* Allow QPSK and 8PSK (even for DVB-S) */ - if (c->modulation != QPSK && c->modulation != PSK_8) { + if (c->modulation != QPSK) { deb_fe("%s: unsupported modulation selected (%d)\n", __func__, c->modulation); return -EOPNOTSUPP; } c->fec_inner = FEC_AUTO; break; - case SYS_DVBS2: + case SYS_DVBS2: /* kept for backwards compatibility */ deb_fe("%s: DVB-S2 delivery system selected\n", __func__); break; + case SYS_TURBO: + deb_fe("%s: Turbo-FEC delivery system selected\n", __func__); + break; default: deb_fe("%s: unsupported delivery system selected (%d)\n", @@ -189,7 +195,10 @@ static int gp8psk_fe_set_frontend(struct dvb_frontend* fe, default: cmd[9] = 5; break; } - cmd[8] = ADV_MOD_DVB_QPSK; + if (c->delivery_system == SYS_TURBO) + cmd[8] = ADV_MOD_TURBO_QPSK; + else + cmd[8] = ADV_MOD_DVB_QPSK; break; case PSK_8: /* PSK_8 is for compatibility with DN */ cmd[8] = ADV_MOD_TURBO_8PSK; diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c index 1cb3d9a..5f71284 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.c +++ b/drivers/media/dvb/dvb-usb/gp8psk.c @@ -230,7 +230,7 @@ static int gp8psk_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) static int gp8psk_frontend_attach(struct dvb_usb_adapter *adap) { - adap->fe = gp8psk_fe_attach(adap->dev); + adap->fe_adap[0].fe = gp8psk_fe_attach(adap->dev); return 0; } @@ -268,6 +268,8 @@ static struct dvb_usb_device_properties gp8psk_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = gp8psk_streaming_ctrl, .frontend_attach = gp8psk_frontend_attach, /* parameter for the MPEG2-data transfer */ @@ -281,6 +283,7 @@ static struct dvb_usb_device_properties gp8psk_properties = { } } }, + }}, } }, .power_ctrl = gp8psk_power_ctrl, diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h index 831749a..ed32b9d 100644 --- a/drivers/media/dvb/dvb-usb/gp8psk.h +++ b/drivers/media/dvb/dvb-usb/gp8psk.h @@ -78,9 +78,6 @@ extern int dvb_usb_gp8psk_debug; #define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */ #define GET_USB_SPEED 0x07 - #define USB_SPEED_LOW 0 - #define USB_SPEED_FULL 1 - #define USB_SPEED_HIGH 2 #define RESET_FX2 0x13 diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c index 37b1469..c7ad854 100644 --- a/drivers/media/dvb/dvb-usb/lmedm04.c +++ b/drivers/media/dvb/dvb-usb/lmedm04.c @@ -162,7 +162,7 @@ static int lme2510_usb_talk(struct dvb_usb_device *d, int ret = 0; if (st->usb_buffer == NULL) { - st->usb_buffer = kmalloc(512, GFP_KERNEL); + st->usb_buffer = kmalloc(64, GFP_KERNEL); if (st->usb_buffer == NULL) { info("MEM Error no memory"); return -ENOMEM; @@ -175,8 +175,8 @@ static int lme2510_usb_talk(struct dvb_usb_device *d, if (ret < 0) return -EAGAIN; - /* the read/write capped at 512 */ - memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen); + /* the read/write capped at 64 */ + memcpy(buff, wbuf, (wlen < 64) ? wlen : 64); ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01)); @@ -186,8 +186,8 @@ static int lme2510_usb_talk(struct dvb_usb_device *d, ret |= usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, 0x01)); - ret |= lme2510_bulk_read(d->udev, buff, (rlen > 512) ? - 512 : rlen , 0x01); + ret |= lme2510_bulk_read(d->udev, buff, (rlen < 64) ? + rlen : 64 , 0x01); if (rlen > 0) memcpy(rbuf, buff, rlen); @@ -326,14 +326,16 @@ static void lme2510_int_response(struct urb *lme_urb) static int lme2510_int_read(struct dvb_usb_adapter *adap) { + struct dvb_usb_device *d = adap->dev; struct lme2510_state *lme_int = adap->dev->priv; + struct usb_host_endpoint *ep; lme_int->lme_urb = usb_alloc_urb(0, GFP_ATOMIC); if (lme_int->lme_urb == NULL) return -ENOMEM; - lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 5000, GFP_ATOMIC, + lme_int->buffer = usb_alloc_coherent(adap->dev->udev, 128, GFP_ATOMIC, &lme_int->lme_urb->transfer_dma); if (lme_int->buffer == NULL) @@ -343,10 +345,16 @@ static int lme2510_int_read(struct dvb_usb_adapter *adap) adap->dev->udev, usb_rcvintpipe(adap->dev->udev, 0xa), lme_int->buffer, - 4096, + 128, lme2510_int_response, adap, - 11); + 8); + + /* Quirk of pipe reporting PIPE_BULK but behaves as interrupt */ + ep = usb_pipe_endpoint(d->udev, lme_int->lme_urb->pipe); + + if (usb_endpoint_type(&ep->desc) == USB_ENDPOINT_XFER_BULK) + lme_int->lme_urb->pipe = usb_rcvbulkpipe(d->udev, 0xa), lme_int->lme_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; @@ -580,7 +588,7 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], { struct dvb_usb_device *d = i2c_get_adapdata(adap); struct lme2510_state *st = d->priv; - static u8 obuf[64], ibuf[512]; + static u8 obuf[64], ibuf[64]; int i, read, read_o; u16 len; u8 gate = st->i2c_gate; @@ -621,7 +629,7 @@ static int lme2510_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], len = msg[i].len+3; } - if (lme2510_msg(d, obuf, len, ibuf, 512) < 0) { + if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) { deb_info(1, "i2c transfer failed."); return -EAGAIN; } @@ -941,7 +949,7 @@ static int lme_name(struct dvb_usb_adapter *adap) const char *desc = adap->dev->desc->name; char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395", " SHARP:BS2F7HZ0194"}; - char *name = adap->fe->ops.info.name; + char *name = adap->fe_adap[0].fe->ops.info.name; strlcpy(name, desc, 128); strlcat(name, fe_name[st->tuner_config], 128); @@ -958,10 +966,10 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) st->i2c_talk_onoff = 1; st->i2c_gate = 4; - adap->fe = dvb_attach(tda10086_attach, &tda10086_config, + adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap); - if (adap->fe) { + if (adap->fe_adap[0].fe) { info("TUN Found Frontend TDA10086"); st->i2c_tuner_gate_w = 4; st->i2c_tuner_gate_r = 4; @@ -975,9 +983,9 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) } st->i2c_gate = 4; - adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config, + adap->fe_adap[0].fe = dvb_attach(stv0299_attach, &sharp_z0194_config, &adap->dev->i2c_adap); - if (adap->fe) { + if (adap->fe_adap[0].fe) { info("FE Found Stv0299"); st->i2c_tuner_gate_w = 4; st->i2c_tuner_gate_r = 5; @@ -991,9 +999,9 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) } st->i2c_gate = 5; - adap->fe = dvb_attach(stv0288_attach, &lme_config, + adap->fe_adap[0].fe = dvb_attach(stv0288_attach, &lme_config, &adap->dev->i2c_adap); - if (adap->fe) { + if (adap->fe_adap[0].fe) { info("FE Found Stv0288"); st->i2c_tuner_gate_w = 4; st->i2c_tuner_gate_r = 5; @@ -1010,15 +1018,15 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap) end: if (ret) { - if (adap->fe) { - dvb_frontend_detach(adap->fe); - adap->fe = NULL; + if (adap->fe_adap[0].fe) { + dvb_frontend_detach(adap->fe_adap[0].fe); + adap->fe_adap[0].fe = NULL; } adap->dev->props.rc.core.rc_codes = NULL; return -ENODEV; } - adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; + adap->fe_adap[0].fe->ops.set_voltage = dm04_lme2510_set_voltage; ret = lme_name(adap); return ret; } @@ -1031,17 +1039,17 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) switch (st->tuner_config) { case TUNER_LG: - if (dvb_attach(tda826x_attach, adap->fe, 0xc0, + if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0xc0, &adap->dev->i2c_adap, 1)) ret = st->tuner_config; break; case TUNER_S7395: - if (dvb_attach(ix2505v_attach , adap->fe, &lme_tuner, + if (dvb_attach(ix2505v_attach , adap->fe_adap[0].fe, &lme_tuner, &adap->dev->i2c_adap)) ret = st->tuner_config; break; case TUNER_S0194: - if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0, + if (dvb_attach(dvb_pll_attach , adap->fe_adap[0].fe, 0xc0, &adap->dev->i2c_adap, DVB_PLL_OPERA1)) ret = st->tuner_config; break; @@ -1145,6 +1153,8 @@ static struct dvb_usb_device_properties lme2510_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER| DVB_USB_ADAP_NEED_PID_FILTERING| DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1166,6 +1176,7 @@ static struct dvb_usb_device_properties lme2510_properties = { } } } + }}, } }, .rc.core = { @@ -1193,6 +1204,8 @@ static struct dvb_usb_device_properties lme2510c_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER| DVB_USB_ADAP_NEED_PID_FILTERING| DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1214,6 +1227,7 @@ static struct dvb_usb_device_properties lme2510c_properties = { } } } + }}, } }, .rc.core = { @@ -1241,7 +1255,7 @@ static void *lme2510_exit_int(struct dvb_usb_device *d) void *buffer = NULL; if (adap != NULL) { - lme2510_kill_urb(&adap->stream); + lme2510_kill_urb(&adap->fe_adap[0].stream); adap->feedcount = 0; } @@ -1255,7 +1269,7 @@ static void *lme2510_exit_int(struct dvb_usb_device *d) if (st->lme_urb != NULL) { usb_kill_urb(st->lme_urb); - usb_free_coherent(d->udev, 5000, st->buffer, + usb_free_coherent(d->udev, 128, st->buffer, st->lme_urb->transfer_dma); info("Interrupt Service Stopped"); } @@ -1306,5 +1320,5 @@ module_exit(lme2510_module_exit); MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); -MODULE_VERSION("1.88"); +MODULE_VERSION("1.90"); MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c index 9456792..a1e1287 100644 --- a/drivers/media/dvb/dvb-usb/m920x.c +++ b/drivers/media/dvb/dvb-usb/m920x.c @@ -86,12 +86,12 @@ static int m920x_init(struct dvb_usb_device *d, struct m920x_inits *rc_seq) } for (i = 0; i < d->props.num_adapters; i++) - flags |= d->adapter[i].props.caps; + flags |= d->adapter[i].props.fe[0].caps; /* Some devices(Dposh) might crash if we attempt touch at all. */ if (flags & DVB_USB_ADAP_HAS_PID_FILTER) { for (i = 0; i < d->props.num_adapters; i++) { - epi = d->adapter[i].props.stream.endpoint - 0x81; + epi = d->adapter[i].props.fe[0].stream.endpoint - 0x81; if (epi < 0 || epi >= M9206_MAX_ADAPTERS) { printk(KERN_INFO "m920x: Unexpected adapter endpoint!\n"); @@ -292,7 +292,7 @@ static int m920x_update_filters(struct dvb_usb_adapter *adap) struct m920x_state *m = adap->dev->priv; int enabled = m->filtering_enabled[adap->id]; int i, ret = 0, filter = 0; - int ep = adap->props.stream.endpoint; + int ep = adap->props.fe[0].stream.endpoint; for (i = 0; i < M9206_MAX_FILTERS; i++) if (m->filters[adap->id][i] == 8192) @@ -501,9 +501,10 @@ static int m920x_mt352_frontend_attach(struct dvb_usb_adapter *adap) { deb("%s\n",__func__); - if ((adap->fe = dvb_attach(mt352_attach, - &m920x_mt352_config, - &adap->dev->i2c_adap)) == NULL) + adap->fe_adap[0].fe = dvb_attach(mt352_attach, + &m920x_mt352_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) == NULL) return -EIO; return 0; @@ -513,9 +514,10 @@ static int m920x_tda10046_08_frontend_attach(struct dvb_usb_adapter *adap) { deb("%s\n",__func__); - if ((adap->fe = dvb_attach(tda10046_attach, - &m920x_tda10046_08_config, - &adap->dev->i2c_adap)) == NULL) + adap->fe_adap[0].fe = dvb_attach(tda10046_attach, + &m920x_tda10046_08_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) == NULL) return -EIO; return 0; @@ -525,9 +527,10 @@ static int m920x_tda10046_0b_frontend_attach(struct dvb_usb_adapter *adap) { deb("%s\n",__func__); - if ((adap->fe = dvb_attach(tda10046_attach, - &m920x_tda10046_0b_config, - &adap->dev->i2c_adap)) == NULL) + adap->fe_adap[0].fe = dvb_attach(tda10046_attach, + &m920x_tda10046_0b_config, + &adap->dev->i2c_adap); + if ((adap->fe_adap[0].fe) == NULL) return -EIO; return 0; @@ -537,7 +540,7 @@ static int m920x_qt1010_tuner_attach(struct dvb_usb_adapter *adap) { deb("%s\n",__func__); - if (dvb_attach(qt1010_attach, adap->fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL) + if (dvb_attach(qt1010_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, &m920x_qt1010_config) == NULL) return -ENODEV; return 0; @@ -547,7 +550,7 @@ static int m920x_tda8275_60_tuner_attach(struct dvb_usb_adapter *adap) { deb("%s\n",__func__); - if (dvb_attach(tda827x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL) + if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, NULL) == NULL) return -ENODEV; return 0; @@ -557,7 +560,7 @@ static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap) { deb("%s\n",__func__); - if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) + if (dvb_attach(tda827x_attach, adap->fe_adap[0].fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) return -ENODEV; return 0; @@ -565,7 +568,7 @@ static int m920x_tda8275_61_tuner_attach(struct dvb_usb_adapter *adap) static int m920x_fmd1216me_tuner_attach(struct dvb_usb_adapter *adap) { - dvb_attach(simple_tuner_attach, adap->fe, + dvb_attach(simple_tuner_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0x61, TUNER_PHILIPS_FMD1216ME_MK3); return 0; @@ -807,6 +810,9 @@ static struct dvb_usb_device_properties megasky_properties = { .identify_state = m920x_identify_state, .num_adapters = 1, .adapter = {{ + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -827,6 +833,7 @@ static struct dvb_usb_device_properties megasky_properties = { } } }, + }}, }}, .i2c_algo = &m920x_i2c_algo, @@ -851,6 +858,9 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = { .identify_state = m920x_identify_state, .num_adapters = 1, .adapter = {{ + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -871,6 +881,7 @@ static struct dvb_usb_device_properties digivox_mini_ii_properties = { } } }, + }}, }}, .i2c_algo = &m920x_i2c_algo, @@ -910,6 +921,9 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = { .identify_state = m920x_identify_state, .num_adapters = 2, .adapter = {{ + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -929,7 +943,11 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = { .buffersize = 512, } } + }}, }},{ + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -949,6 +967,7 @@ static struct dvb_usb_device_properties tvwalkertwin_properties = { .buffersize = 512, } } + }}, }, }}, .i2c_algo = &m920x_i2c_algo, @@ -974,6 +993,8 @@ static struct dvb_usb_device_properties dposh_properties = { .identify_state = m920x_identify_state, .num_adapters = 1, .adapter = {{ + .num_frontends = 1, + .fe = {{ /* Hardware pid filters don't work with this device/firmware */ .frontend_attach = m920x_mt352_frontend_attach, @@ -989,6 +1010,7 @@ static struct dvb_usb_device_properties dposh_properties = { } } }, + }}, }}, .i2c_algo = &m920x_i2c_algo, @@ -1019,6 +1041,9 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = { .identify_state = m920x_identify_state, .num_adapters = 1, .adapter = {{ + .num_frontends = 1, + .fe = {{ + .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, @@ -1041,6 +1066,7 @@ static struct dvb_usb_device_properties pinnacle_pctv310e_properties = { } } }, + }}, } }, .i2c_algo = &m920x_i2c_algo, diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index bc350e9..21384da 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -166,6 +166,8 @@ static struct dvb_usb_device_properties nova_t_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF, .pid_filter_count = 32, @@ -186,7 +188,7 @@ static struct dvb_usb_device_properties nova_t_properties = { } } }, - + }}, .size_of_priv = sizeof(struct dibusb_state), } }, diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c index 2e4fab7..98fd9a6 100644 --- a/drivers/media/dvb/dvb-usb/opera1.c +++ b/drivers/media/dvb/dvb-usb/opera1.c @@ -263,10 +263,10 @@ static struct stv0299_config opera1_stv0299_config = { static int opera1_frontend_attach(struct dvb_usb_adapter *d) { - if ((d->fe = - dvb_attach(stv0299_attach, &opera1_stv0299_config, - &d->dev->i2c_adap)) != NULL) { - d->fe->ops.set_voltage = opera1_set_voltage; + d->fe_adap[0].fe = dvb_attach(stv0299_attach, &opera1_stv0299_config, + &d->dev->i2c_adap); + if ((d->fe_adap[0].fe) != NULL) { + d->fe_adap[0].fe->ops.set_voltage = opera1_set_voltage; return 0; } info("not attached stv0299"); @@ -276,7 +276,7 @@ static int opera1_frontend_attach(struct dvb_usb_adapter *d) static int opera1_tuner_attach(struct dvb_usb_adapter *adap) { dvb_attach( - dvb_pll_attach, adap->fe, 0xc0>>1, + dvb_pll_attach, adap->fe_adap[0].fe, 0xc0>>1, &adap->dev->i2c_adap, DVB_PLL_OPERA1 ); return 0; @@ -516,6 +516,8 @@ static struct dvb_usb_device_properties opera1_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = opera1_frontend_attach, .streaming_ctrl = opera1_streaming_ctrl, .tuner_attach = opera1_tuner_attach, @@ -535,6 +537,7 @@ static struct dvb_usb_device_properties opera1_properties = { } } }, + }}, } }, .num_device_descs = 1, diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c index 08f8842..0998fe9 100644 --- a/drivers/media/dvb/dvb-usb/technisat-usb2.c +++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c @@ -292,7 +292,7 @@ static void technisat_usb2_green_led_control(struct work_struct *work) { struct technisat_usb2_state *state = container_of(work, struct technisat_usb2_state, green_led_work.work); - struct dvb_frontend *fe = state->dev->adapter[0].fe; + struct dvb_frontend *fe = state->dev->adapter[0].fe_adap[0].fe; if (state->power_state == 0) goto schedule; @@ -505,14 +505,14 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) struct usb_device *udev = a->dev->udev; int ret; - a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config, + a->fe_adap[0].fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config, &a->dev->i2c_adap, STV090x_DEMODULATOR_0); - if (a->fe) { + if (a->fe_adap[0].fe) { struct stv6110x_devctl *ctl; ctl = dvb_attach(stv6110x_attach, - a->fe, + a->fe_adap[0].fe, &technisat_usb2_stv6110x_config, &a->dev->i2c_adap); @@ -532,8 +532,8 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) /* call the init function once to initialize tuner's clock output divider and demod's master clock */ - if (a->fe->ops.init) - a->fe->ops.init(a->fe); + if (a->fe_adap[0].fe->ops.init) + a->fe_adap[0].fe->ops.init(a->fe_adap[0].fe); if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0) return -EAGAIN; @@ -548,20 +548,20 @@ static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a) if (ret != 0) err("could not set IF_CLK to external"); - a->fe->ops.set_voltage = technisat_usb2_set_voltage; + a->fe_adap[0].fe->ops.set_voltage = technisat_usb2_set_voltage; /* if everything was successful assign a nice name to the frontend */ - strlcpy(a->fe->ops.info.name, a->dev->desc->name, - sizeof(a->fe->ops.info.name)); + strlcpy(a->fe_adap[0].fe->ops.info.name, a->dev->desc->name, + sizeof(a->fe_adap[0].fe->ops.info.name)); } else { - dvb_frontend_detach(a->fe); - a->fe = NULL; + dvb_frontend_detach(a->fe_adap[0].fe); + a->fe_adap[0].fe = NULL; } } technisat_usb2_set_led_timer(a->dev, 1, 1); - return a->fe == NULL ? -ENODEV : 0; + return a->fe_adap[0].fe == NULL ? -ENODEV : 0; } /* Remote control */ @@ -697,6 +697,8 @@ static struct dvb_usb_device_properties technisat_usb2_devices = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = technisat_usb2_frontend_attach, .stream = { @@ -711,7 +713,7 @@ static struct dvb_usb_device_properties technisat_usb2_devices = { } } }, - + }}, .size_of_priv = 0, }, }, @@ -765,10 +767,8 @@ static void technisat_usb2_disconnect(struct usb_interface *intf) /* work and stuff was only created when the device is is hot-state */ if (dev != NULL) { struct technisat_usb2_state *state = dev->priv; - if (state != NULL) { + if (state != NULL) cancel_delayed_work_sync(&state->green_led_work); - flush_scheduled_work(); - } } dvb_usb_device_exit(intf); diff --git a/drivers/media/dvb/dvb-usb/ttusb2.c b/drivers/media/dvb/dvb-usb/ttusb2.c index 0d4709f..ea4eab8 100644 --- a/drivers/media/dvb/dvb-usb/ttusb2.c +++ b/drivers/media/dvb/dvb-usb/ttusb2.c @@ -30,18 +30,43 @@ #include "tda826x.h" #include "tda10086.h" #include "tda1002x.h" +#include "tda10048.h" #include "tda827x.h" #include "lnbp21.h" +/* CA */ +#include "dvb_ca_en50221.h" /* debug */ static int dvb_usb_ttusb2_debug; #define deb_info(args...) dprintk(dvb_usb_ttusb2_debug,0x01,args) module_param_named(debug,dvb_usb_ttusb2_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able))." DVB_USB_DEBUG_STATUS); +static int dvb_usb_ttusb2_debug_ci; +module_param_named(debug_ci,dvb_usb_ttusb2_debug_ci, int, 0644); +MODULE_PARM_DESC(debug_ci, "set debugging ci." DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +#define ci_dbg(format, arg...) \ +do { \ + if (dvb_usb_ttusb2_debug_ci) \ + printk(KERN_DEBUG DVB_USB_LOG_PREFIX \ + ": %s " format "\n" , __func__, ## arg); \ +} while (0) + +enum { + TT3650_CMD_CI_TEST = 0x40, + TT3650_CMD_CI_RD_CTRL, + TT3650_CMD_CI_WR_CTRL, + TT3650_CMD_CI_RD_ATTR, + TT3650_CMD_CI_WR_ATTR, + TT3650_CMD_CI_RESET, + TT3650_CMD_CI_SET_VIDEO_PORT +}; + struct ttusb2_state { + struct dvb_ca_en50221 ca; + struct mutex ca_mutex; u8 id; u16 last_rc_key; }; @@ -78,11 +103,260 @@ static int ttusb2_msg(struct dvb_usb_device *d, u8 cmd, return 0; } +/* ci */ +static int tt3650_ci_msg(struct dvb_usb_device *d, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) +{ + int ret; + u8 rx[60];/* (64 -4) */ + ret = ttusb2_msg(d, cmd, data, write_len, rx, read_len); + if (!ret) + memcpy(data, rx, read_len); + return ret; +} + +static int tt3650_ci_msg_locked(struct dvb_ca_en50221 *ca, u8 cmd, u8 *data, unsigned int write_len, unsigned int read_len) +{ + struct dvb_usb_device *d = ca->data; + struct ttusb2_state *state = d->priv; + int ret; + + mutex_lock(&state->ca_mutex); + ret = tt3650_ci_msg(d, cmd, data, write_len, read_len); + mutex_unlock(&state->ca_mutex); + + return ret; +} + +static int tt3650_ci_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address) +{ + u8 buf[3]; + int ret = 0; + + if (slot) + return -EINVAL; + + buf[0] = (address >> 8) & 0x0F; + buf[1] = address; + + + ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_ATTR, buf, 2, 3); + + ci_dbg("%04x -> %d 0x%02x", address, ret, buf[2]); + + if (ret < 0) + return ret; + + return buf[2]; +} + +static int tt3650_ci_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value) +{ + u8 buf[3]; + + ci_dbg("%d 0x%04x 0x%02x", slot, address, value); + + if (slot) + return -EINVAL; + + buf[0] = (address >> 8) & 0x0F; + buf[1] = address; + buf[2] = value; + + return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_ATTR, buf, 3, 3); +} + +static int tt3650_ci_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address) +{ + u8 buf[2]; + int ret; + + if (slot) + return -EINVAL; + + buf[0] = address & 3; + + ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_RD_CTRL, buf, 1, 2); + + ci_dbg("0x%02x -> %d 0x%02x", address, ret, buf[1]); + + if (ret < 0) + return ret; + + return buf[1]; +} + +static int tt3650_ci_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value) +{ + u8 buf[2]; + + ci_dbg("%d 0x%02x 0x%02x", slot, address, value); + + if (slot) + return -EINVAL; + + buf[0] = address; + buf[1] = value; + + return tt3650_ci_msg_locked(ca, TT3650_CMD_CI_WR_CTRL, buf, 2, 2); +} + +static int tt3650_ci_set_video_port(struct dvb_ca_en50221 *ca, int slot, int enable) +{ + u8 buf[1]; + int ret; + + ci_dbg("%d %d", slot, enable); + + if (slot) + return -EINVAL; + + buf[0] = enable; + + ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1); + if (ret < 0) + return ret; + + if (enable != buf[0]) { + err("CI not %sabled.", enable ? "en" : "dis"); + return -EIO; + } + + return 0; +} + +static int tt3650_ci_slot_shutdown(struct dvb_ca_en50221 *ca, int slot) +{ + return tt3650_ci_set_video_port(ca, slot, 0); +} + +static int tt3650_ci_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot) +{ + return tt3650_ci_set_video_port(ca, slot, 1); +} + +static int tt3650_ci_slot_reset(struct dvb_ca_en50221 *ca, int slot) +{ + struct dvb_usb_device *d = ca->data; + struct ttusb2_state *state = d->priv; + u8 buf[1]; + int ret; + + ci_dbg("%d", slot); + + if (slot) + return -EINVAL; + + buf[0] = 0; + + mutex_lock(&state->ca_mutex); + + ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1); + if (ret) + goto failed; + + msleep(500); + + buf[0] = 1; + + ret = tt3650_ci_msg(d, TT3650_CMD_CI_RESET, buf, 1, 1); + if (ret) + goto failed; + + msleep(500); + + buf[0] = 0; /* FTA */ + + ret = tt3650_ci_msg(d, TT3650_CMD_CI_SET_VIDEO_PORT, buf, 1, 1); + + msleep(1100); + + failed: + mutex_unlock(&state->ca_mutex); + + return ret; +} + +static int tt3650_ci_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open) +{ + u8 buf[1]; + int ret; + + if (slot) + return -EINVAL; + + ret = tt3650_ci_msg_locked(ca, TT3650_CMD_CI_TEST, buf, 0, 1); + if (ret) + return ret; + + if (1 == buf[0]) { + return DVB_CA_EN50221_POLL_CAM_PRESENT | + DVB_CA_EN50221_POLL_CAM_READY; + } + return 0; +} + +static void tt3650_ci_uninit(struct dvb_usb_device *d) +{ + struct ttusb2_state *state; + + ci_dbg(""); + + if (NULL == d) + return; + + state = d->priv; + if (NULL == state) + return; + + if (NULL == state->ca.data) + return; + + dvb_ca_en50221_release(&state->ca); + + memset(&state->ca, 0, sizeof(state->ca)); +} + +static int tt3650_ci_init(struct dvb_usb_adapter *a) +{ + struct dvb_usb_device *d = a->dev; + struct ttusb2_state *state = d->priv; + int ret; + + ci_dbg(""); + + mutex_init(&state->ca_mutex); + + state->ca.owner = THIS_MODULE; + state->ca.read_attribute_mem = tt3650_ci_read_attribute_mem; + state->ca.write_attribute_mem = tt3650_ci_write_attribute_mem; + state->ca.read_cam_control = tt3650_ci_read_cam_control; + state->ca.write_cam_control = tt3650_ci_write_cam_control; + state->ca.slot_reset = tt3650_ci_slot_reset; + state->ca.slot_shutdown = tt3650_ci_slot_shutdown; + state->ca.slot_ts_enable = tt3650_ci_slot_ts_enable; + state->ca.poll_slot_status = tt3650_ci_poll_slot_status; + state->ca.data = d; + + ret = dvb_ca_en50221_init(&a->dvb_adap, + &state->ca, + /* flags */ 0, + /* n_slots */ 1); + if (ret) { + err("Cannot initialize CI: Error %d.", ret); + memset(&state->ca, 0, sizeof(state->ca)); + return ret; + } + + info("CI initialized."); + + return 0; +} + static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); static u8 obuf[60], ibuf[60]; - int i,read; + int i, write_read, read; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -91,28 +365,35 @@ static int ttusb2_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num warn("more than 2 i2c messages at a time is not handled yet. TODO."); for (i = 0; i < num; i++) { - read = i+1 < num && (msg[i+1].flags & I2C_M_RD); + write_read = i+1 < num && (msg[i+1].flags & I2C_M_RD); + read = msg[i].flags & I2C_M_RD; - obuf[0] = (msg[i].addr << 1) | read; - obuf[1] = msg[i].len; + obuf[0] = (msg[i].addr << 1) | (write_read | read); + if (read) + obuf[1] = 0; + else + obuf[1] = msg[i].len; /* read request */ - if (read) + if (write_read) obuf[2] = msg[i+1].len; + else if (read) + obuf[2] = msg[i].len; else obuf[2] = 0; - memcpy(&obuf[3],msg[i].buf,msg[i].len); + memcpy(&obuf[3], msg[i].buf, msg[i].len); if (ttusb2_msg(d, CMD_I2C_XFER, obuf, msg[i].len+3, ibuf, obuf[2] + 3) < 0) { err("i2c transfer failed."); break; } - if (read) { - memcpy(msg[i+1].buf,&ibuf[3],msg[i+1].len); + if (write_read) { + memcpy(msg[i+1].buf, &ibuf[3], msg[i+1].len); i++; - } + } else if (read) + memcpy(msg[i].buf, &ibuf[3], msg[i].len); } mutex_unlock(&d->i2c_mutex); @@ -190,12 +471,31 @@ static struct tda10023_config tda10023_config = { .deltaf = 0xa511, }; +static struct tda10048_config tda10048_config = { + .demod_address = 0x10 >> 1, + .output_mode = TDA10048_PARALLEL_OUTPUT, + .inversion = TDA10048_INVERSION_ON, + .dtv6_if_freq_khz = TDA10048_IF_4000, + .dtv7_if_freq_khz = TDA10048_IF_4500, + .dtv8_if_freq_khz = TDA10048_IF_5000, + .clk_freq_khz = TDA10048_CLK_16000, + .no_firmware = 1, + .set_pll = true , + .pll_m = 5, + .pll_n = 3, + .pll_p = 0, +}; + +static struct tda827x_config tda827x_config = { + .config = 0, +}; + static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev,0,3) < 0) err("set interface to alts=3 failed"); - if ((adap->fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) { + if ((adap->fe_adap[0].fe = dvb_attach(tda10086_attach, &tda10086_config, &adap->dev->i2c_adap)) == NULL) { deb_info("TDA10086 attach failed\n"); return -ENODEV; } @@ -203,20 +503,57 @@ static int ttusb2_frontend_tda10086_attach(struct dvb_usb_adapter *adap) return 0; } +static int ttusb2_ct3650_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->dvb->priv; + + return adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, enable); +} + static int ttusb2_frontend_tda10023_attach(struct dvb_usb_adapter *adap) { if (usb_set_interface(adap->dev->udev, 0, 3) < 0) err("set interface to alts=3 failed"); - if ((adap->fe = dvb_attach(tda10023_attach, &tda10023_config, &adap->dev->i2c_adap, 0x48)) == NULL) { - deb_info("TDA10023 attach failed\n"); - return -ENODEV; + + if (adap->fe_adap[0].fe == NULL) { + /* FE 0 DVB-C */ + adap->fe_adap[0].fe = dvb_attach(tda10023_attach, + &tda10023_config, &adap->dev->i2c_adap, 0x48); + + if (adap->fe_adap[0].fe == NULL) { + deb_info("TDA10023 attach failed\n"); + return -ENODEV; + } + tt3650_ci_init(adap); + } else { + adap->fe_adap[1].fe = dvb_attach(tda10048_attach, + &tda10048_config, &adap->dev->i2c_adap); + + if (adap->fe_adap[1].fe == NULL) { + deb_info("TDA10048 attach failed\n"); + return -ENODEV; + } + + /* tuner is behind TDA10023 I2C-gate */ + adap->fe_adap[1].fe->ops.i2c_gate_ctrl = ttusb2_ct3650_i2c_gate_ctrl; + } + return 0; } static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) { - if (dvb_attach(tda827x_attach, adap->fe, 0x61, &adap->dev->i2c_adap, NULL) == NULL) { + struct dvb_frontend *fe; + + /* MFE: select correct FE to attach tuner since that's called twice */ + if (adap->fe_adap[1].fe == NULL) + fe = adap->fe_adap[0].fe; + else + fe = adap->fe_adap[1].fe; + + /* attach tuner */ + if (dvb_attach(tda827x_attach, fe, 0x61, &adap->dev->i2c_adap, &tda827x_config) == NULL) { printk(KERN_ERR "%s: No tda827x found!\n", __func__); return -ENODEV; } @@ -225,12 +562,12 @@ static int ttusb2_tuner_tda827x_attach(struct dvb_usb_adapter *adap) static int ttusb2_tuner_tda826x_attach(struct dvb_usb_adapter *adap) { - if (dvb_attach(tda826x_attach, adap->fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { + if (dvb_attach(tda826x_attach, adap->fe_adap[0].fe, 0x60, &adap->dev->i2c_adap, 0) == NULL) { deb_info("TDA8263 attach failed\n"); return -ENODEV; } - if (dvb_attach(lnbp21_attach, adap->fe, &adap->dev->i2c_adap, 0, 0) == NULL) { + if (dvb_attach(lnbp21_attach, adap->fe_adap[0].fe, &adap->dev->i2c_adap, 0, 0) == NULL) { deb_info("LNBP21 attach failed\n"); return -ENODEV; } @@ -242,6 +579,14 @@ static struct dvb_usb_device_properties ttusb2_properties; static struct dvb_usb_device_properties ttusb2_properties_s2400; static struct dvb_usb_device_properties ttusb2_properties_ct3650; +static void ttusb2_usb_disconnect(struct usb_interface *intf) +{ + struct dvb_usb_device *d = usb_get_intfdata(intf); + + tt3650_ci_uninit(d); + dvb_usb_device_exit(intf); +} + static int ttusb2_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -277,6 +622,8 @@ static struct dvb_usb_device_properties ttusb2_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = NULL, // ttusb2_streaming_ctrl, .frontend_attach = ttusb2_frontend_tda10086_attach, @@ -295,6 +642,7 @@ static struct dvb_usb_device_properties ttusb2_properties = { } } } + }}, } }, @@ -329,6 +677,8 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = NULL, .frontend_attach = ttusb2_frontend_tda10086_attach, @@ -347,6 +697,7 @@ static struct dvb_usb_device_properties ttusb2_properties_s2400 = { } } } + }}, } }, @@ -383,6 +734,27 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { .num_adapters = 1, .adapter = { { + .num_frontends = 2, + .fe = {{ + .streaming_ctrl = NULL, + + .frontend_attach = ttusb2_frontend_tda10023_attach, + .tuner_attach = ttusb2_tuner_tda827x_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_ISOC, + .count = 5, + .endpoint = 0x02, + .u = { + .isoc = { + .framesperurb = 4, + .framesize = 940, + .interval = 1, + } + } + } + }, { .streaming_ctrl = NULL, .frontend_attach = ttusb2_frontend_tda10023_attach, @@ -401,6 +773,7 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { } } } + }}, }, }, @@ -422,7 +795,7 @@ static struct dvb_usb_device_properties ttusb2_properties_ct3650 = { static struct usb_driver ttusb2_driver = { .name = "dvb_usb_ttusb2", .probe = ttusb2_probe, - .disconnect = dvb_usb_device_exit, + .disconnect = ttusb2_usb_disconnect, .id_table = ttusb2_table, }; diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 118aab1..463673a 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c @@ -60,14 +60,14 @@ static int umt_mt352_frontend_attach(struct dvb_usb_adapter *adap) umt_config.demod_init = umt_mt352_demod_init; umt_config.demod_address = 0xf; - adap->fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap); + adap->fe_adap[0].fe = dvb_attach(mt352_attach, &umt_config, &adap->dev->i2c_adap); return 0; } static int umt_tuner_attach (struct dvb_usb_adapter *adap) { - dvb_attach(dvb_pll_attach, adap->fe, 0x61, NULL, DVB_PLL_TUA6034); + dvb_attach(dvb_pll_attach, adap->fe_adap[0].fe, 0x61, NULL, DVB_PLL_TUA6034); return 0; } @@ -100,6 +100,8 @@ static struct dvb_usb_device_properties umt_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .streaming_ctrl = dibusb2_0_streaming_ctrl, .frontend_attach = umt_mt352_frontend_attach, .tuner_attach = umt_tuner_attach, @@ -115,7 +117,7 @@ static struct dvb_usb_device_properties umt_properties = { } } }, - + }}, .size_of_priv = sizeof(struct dibusb_state), } }, diff --git a/drivers/media/dvb/dvb-usb/usb-urb.c b/drivers/media/dvb/dvb-usb/usb-urb.c index 86d6893..d62ee0f 100644 --- a/drivers/media/dvb/dvb-usb/usb-urb.c +++ b/drivers/media/dvb/dvb-usb/usb-urb.c @@ -148,7 +148,7 @@ static int usb_bulk_urb_init(struct usb_data_stream *stream) if (!stream->urb_list[i]) { deb_mem("not enough memory for urb_alloc_urb!.\n"); for (j = 0; j < i; j++) - usb_free_urb(stream->urb_list[i]); + usb_free_urb(stream->urb_list[j]); return -ENOMEM; } usb_fill_bulk_urb( stream->urb_list[i], stream->udev, @@ -181,7 +181,7 @@ static int usb_isoc_urb_init(struct usb_data_stream *stream) if (!stream->urb_list[i]) { deb_mem("not enough memory for urb_alloc_urb!\n"); for (j = 0; j < i; j++) - usb_free_urb(stream->urb_list[i]); + usb_free_urb(stream->urb_list[j]); return -ENOMEM; } diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c index 54355f8..45e31f2 100644 --- a/drivers/media/dvb/dvb-usb/vp702x.c +++ b/drivers/media/dvb/dvb-usb/vp702x.c @@ -320,7 +320,7 @@ static int vp702x_frontend_attach(struct dvb_usb_adapter *adap) vp702x_init_pid_filter(adap); - adap->fe = vp702x_fe_attach(adap->dev); + adap->fe_adap[0].fe = vp702x_fe_attach(adap->dev); vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 1, 7, NULL, 0); return 0; @@ -383,6 +383,8 @@ static struct dvb_usb_device_properties vp702x_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, .streaming_ctrl = vp702x_streaming_ctrl, @@ -399,6 +401,7 @@ static struct dvb_usb_device_properties vp702x_properties = { } } }, + }}, .size_of_priv = sizeof(struct vp702x_adapter_state), } }, diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 536c16c..90873af 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -214,7 +214,7 @@ static int vp7045_frontend_attach(struct dvb_usb_adapter *adap) /* Dump the EEPROM */ /* vp7045_read_eeprom(d,buf, 255, FX2_ID_ADDR); */ - adap->fe = vp7045_fe_attach(adap->dev); + adap->fe_adap[0].fe = vp7045_fe_attach(adap->dev); return 0; } @@ -245,6 +245,8 @@ static struct dvb_usb_device_properties vp7045_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 1, + .fe = {{ .frontend_attach = vp7045_frontend_attach, /* parameter for the MPEG2-data transfer */ .stream = { @@ -257,6 +259,7 @@ static struct dvb_usb_device_properties vp7045_properties = { } } }, + }}, } }, .power_ctrl = vp7045_power_ctrl, diff --git a/drivers/media/dvb/dvb-usb/vp7045.h b/drivers/media/dvb/dvb-usb/vp7045.h index 969688f..cf5ec46 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.h +++ b/drivers/media/dvb/dvb-usb/vp7045.h @@ -36,9 +36,6 @@ #define Tuner_Power_OFF 0 #define GET_USB_SPEED 0x07 - #define USB_SPEED_LOW 0 - #define USB_SPEED_FULL 1 - #define USB_SPEED_HIGH 2 #define LOCK_TUNER_COMMAND 0x09 diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c index 21c52e3..489ae82 100644 --- a/drivers/media/dvb/firewire/firedtv-avc.c +++ b/drivers/media/dvb/firewire/firedtv-avc.c @@ -1208,7 +1208,7 @@ int avc_ca_pmt(struct firedtv *fdtv, char *msg, int length) if (r->response != AVC_RESPONSE_ACCEPTED) { dev_err(fdtv->device, "CA PMT failed with response 0x%x\n", r->response); - ret = -EFAULT; + ret = -EACCES; } out: mutex_unlock(&fdtv->avc_mutex); diff --git a/drivers/media/dvb/firewire/firedtv-ci.c b/drivers/media/dvb/firewire/firedtv-ci.c index 8ffb565..e5ebdbf 100644 --- a/drivers/media/dvb/firewire/firedtv-ci.c +++ b/drivers/media/dvb/firewire/firedtv-ci.c @@ -45,11 +45,6 @@ static int fdtv_get_ca_flags(struct firedtv_tuner_status *stat) return flags; } -static int fdtv_ca_reset(struct firedtv *fdtv) -{ - return avc_ca_reset(fdtv) ? -EFAULT : 0; -} - static int fdtv_ca_get_caps(void *arg) { struct ca_caps *cap = arg; @@ -65,12 +60,14 @@ static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) { struct firedtv_tuner_status stat; struct ca_slot_info *slot = arg; + int err; - if (avc_tuner_status(fdtv, &stat)) - return -EFAULT; + err = avc_tuner_status(fdtv, &stat); + if (err) + return err; if (slot->num != 0) - return -EFAULT; + return -EACCES; slot->type = CA_CI; slot->flags = fdtv_get_ca_flags(&stat); @@ -81,21 +78,21 @@ static int fdtv_ca_app_info(struct firedtv *fdtv, void *arg) { struct ca_msg *reply = arg; - return avc_ca_app_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; + return avc_ca_app_info(fdtv, reply->msg, &reply->length); } static int fdtv_ca_info(struct firedtv *fdtv, void *arg) { struct ca_msg *reply = arg; - return avc_ca_info(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; + return avc_ca_info(fdtv, reply->msg, &reply->length); } static int fdtv_ca_get_mmi(struct firedtv *fdtv, void *arg) { struct ca_msg *reply = arg; - return avc_ca_get_mmi(fdtv, reply->msg, &reply->length) ? -EFAULT : 0; + return avc_ca_get_mmi(fdtv, reply->msg, &reply->length); } static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) @@ -111,14 +108,15 @@ static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) err = fdtv_ca_info(fdtv, arg); break; default: - if (avc_tuner_status(fdtv, &stat)) - err = -EFAULT; - else if (stat.ca_mmi == 1) + err = avc_tuner_status(fdtv, &stat); + if (err) + break; + if (stat.ca_mmi == 1) err = fdtv_ca_get_mmi(fdtv, arg); else { dev_info(fdtv->device, "unhandled CA message 0x%08x\n", fdtv->ca_last_command); - err = -EFAULT; + err = -EACCES; } } fdtv->ca_last_command = 0; @@ -141,7 +139,7 @@ static int fdtv_ca_pmt(struct firedtv *fdtv, void *arg) data_length = msg->msg[3]; } - return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length) ? -EFAULT : 0; + return avc_ca_pmt(fdtv, &msg->msg[data_pos], data_length); } static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) @@ -170,7 +168,7 @@ static int fdtv_ca_send_msg(struct firedtv *fdtv, void *arg) default: dev_err(fdtv->device, "unhandled CA message 0x%08x\n", fdtv->ca_last_command); - err = -EFAULT; + err = -EACCES; } return err; } @@ -184,7 +182,7 @@ static int fdtv_ca_ioctl(struct file *file, unsigned int cmd, void *arg) switch (cmd) { case CA_RESET: - err = fdtv_ca_reset(fdtv); + err = avc_ca_reset(fdtv); break; case CA_GET_CAP: err = fdtv_ca_get_caps(arg); diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 44b816f..4a2d2e6 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig @@ -49,6 +49,27 @@ config DVB_STV6110x help A Silicon tuner that supports DVB-S and DVB-S2 modes +comment "Multistandard (cable + terrestrial) frontends" + depends on DVB_CORE + +config DVB_DRXK + tristate "Micronas DRXK based" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + Micronas DRX-K DVB-C/T demodulator. + + Say Y when you want to support this frontend. + +config DVB_TDA18271C2DD + tristate "NXP TDA18271C2 silicon tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + NXP TDA18271 silicon tuner. + + Say Y when you want to support this tuner. + comment "DVB-S (satellite) frontends" depends on DVB_CORE @@ -215,6 +236,13 @@ config DVB_MB86A16 A DVB-S/DSS Direct Conversion reveiver. Say Y when you want to support this frontend. +config DVB_TDA10071 + tristate "NXP TDA10071" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + Say Y when you want to support this frontend. + comment "DVB-T (terrestrial) frontends" depends on DVB_CORE @@ -579,6 +607,16 @@ config DVB_LNBP21 help An SEC control chips. +config DVB_LNBP22 + tristate "LNBP22 SEC controllers" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + LNB power supply and control voltage + regulator chip with step-up converter + and I2C interface. + Say Y when you want to support this chip. + config DVB_ISL6405 tristate "ISL6405 SEC controller" depends on DVB_CORE && I2C @@ -600,6 +638,11 @@ config DVB_ISL6423 help A SEC controller chip from Intersil +config DVB_A8293 + tristate "Allegro A8293" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + config DVB_LGS8GL5 tristate "Silicon Legend LGS-8GL5 demodulator (OFDM)" depends on DVB_CORE && I2C @@ -640,6 +683,14 @@ config DVB_IX2505V help A DVB-S tuner module. Say Y when you want to support this frontend. +config DVB_IT913X_FE + tristate "it913x frontend and it9137 tuner" + 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. + comment "Tools to develop new frontends" config DVB_DUMMY_FE diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 2f3a6f7..f639f67 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile @@ -2,14 +2,15 @@ # Makefile for the kernel DVB frontend device drivers. # -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -EXTRA_CFLAGS += -Idrivers/media/common/tuners/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ +ccflags-y += -Idrivers/media/common/tuners/ stb0899-objs = stb0899_drv.o stb0899_algo.o stv0900-objs = stv0900_core.o stv0900_sw.o au8522-objs = au8522_dig.o au8522_decoder.o drxd-objs = drxd_firm.o drxd_hard.o cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o +drxk-objs := drxk_hard.o obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o @@ -51,6 +52,7 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o +obj-$(CONFIG_DVB_LNBP22) += lnbp22.o obj-$(CONFIG_DVB_ISL6405) += isl6405.o obj-$(CONFIG_DVB_ISL6421) += isl6421.o obj-$(CONFIG_DVB_TDA10086) += tda10086.o @@ -88,4 +90,9 @@ obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o obj-$(CONFIG_DVB_IX2505V) += ix2505v.o obj-$(CONFIG_DVB_STV0367) += stv0367.o obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o +obj-$(CONFIG_DVB_DRXK) += drxk.o +obj-$(CONFIG_DVB_TDA18271C2DD) += tda18271c2dd.o +obj-$(CONFIG_DVB_IT913X_FE) += it913x-fe.o +obj-$(CONFIG_DVB_A8293) += a8293.o +obj-$(CONFIG_DVB_TDA10071) += tda10071.o diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c index b537891..2b248c1 100644 --- a/drivers/media/dvb/frontends/au8522_decoder.c +++ b/drivers/media/dvb/frontends/au8522_decoder.c @@ -692,7 +692,7 @@ static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) /* Interrogate the decoder to see if we are getting a real signal */ lock_status = au8522_readreg(state, 0x00); if (lock_status == 0xa2) - vt->signal = 0x01; + vt->signal = 0xffff; else vt->signal = 0x00; diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c index e9ee555..c341d57 100644 --- a/drivers/media/dvb/frontends/cx24113.c +++ b/drivers/media/dvb/frontends/cx24113.c @@ -31,8 +31,8 @@ static int debug; -#define info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0) -#define err(args...) do { printk(KERN_ERR "CX24113: " args); } while (0) +#define cx_info(args...) do { printk(KERN_INFO "CX24113: " args); } while (0) +#define cx_err(args...) do { printk(KERN_ERR "CX24113: " args); } while (0) #define dprintk(args...) \ do { \ @@ -341,7 +341,7 @@ static void cx24113_calc_pll_nf(struct cx24113_state *state, u16 *n, s32 *f) } while (N < 6 && R < 3); if (N < 6) { - err("strange frequency: N < 6\n"); + cx_err("strange frequency: N < 6\n"); return; } F = freq_hz; @@ -563,7 +563,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, kzalloc(sizeof(struct cx24113_state), GFP_KERNEL); int rc; if (state == NULL) { - err("Unable to kzalloc\n"); + cx_err("Unable to kzalloc\n"); goto error; } @@ -571,7 +571,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, state->config = config; state->i2c = i2c; - info("trying to detect myself\n"); + cx_info("trying to detect myself\n"); /* making a dummy read, because of some expected troubles * after power on */ @@ -579,24 +579,24 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe, rc = cx24113_readreg(state, 0x00); if (rc < 0) { - info("CX24113 not found.\n"); + cx_info("CX24113 not found.\n"); goto error; } state->rev = rc; switch (rc) { case 0x43: - info("detected CX24113 variant\n"); + cx_info("detected CX24113 variant\n"); break; case REV_CX24113: - info("successfully detected\n"); + cx_info("successfully detected\n"); break; default: - err("unsupported device id: %x\n", state->rev); + cx_err("unsupported device id: %x\n", state->rev); goto error; } state->ver = cx24113_readreg(state, 0x01); - info("version: %x\n", state->ver); + cx_info("version: %x\n", state->ver); /* create dvb_frontend */ memcpy(&fe->ops.tuner_ops, &cx24113_tuner_ops, diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c index 95c6465..4ff6d15 100644 --- a/drivers/media/dvb/frontends/cx24116.c +++ b/drivers/media/dvb/frontends/cx24116.c @@ -963,6 +963,10 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, struct cx24116_state *state = fe->demodulator_priv; int i, ret; + /* Validate length */ + if (d->msg_len > sizeof(d->msg)) + return -EINVAL; + /* Dump DiSEqC message */ if (debug) { printk(KERN_INFO "cx24116: %s(", __func__); @@ -974,10 +978,6 @@ static int cx24116_send_diseqc_msg(struct dvb_frontend *fe, printk(") toneburst=%d\n", toneburst); } - /* Validate length */ - if (d->msg_len > (CX24116_ARGLEN - CX24116_DISEQC_MSGOFS)) - return -EINVAL; - /* DiSEqC message */ for (i = 0; i < d->msg_len; i++) state->dsec_cmd.args[CX24116_DISEQC_MSGOFS + i] = d->msg[i]; @@ -1452,11 +1452,7 @@ tuned: /* Set/Reset B/W */ cmd.args[0x00] = CMD_BANDWIDTH; cmd.args[0x01] = 0x00; cmd.len = 0x02; - ret = cx24116_cmd_execute(fe, &cmd); - if (ret != 0) - return ret; - - return ret; + return cx24116_cmd_execute(fe, &cmd); } static int cx24116_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *params, diff --git a/drivers/media/dvb/frontends/cxd2820r.h b/drivers/media/dvb/frontends/cxd2820r.h index ad17845..03cab7b 100644 --- a/drivers/media/dvb/frontends/cxd2820r.h +++ b/drivers/media/dvb/frontends/cxd2820r.h @@ -55,13 +55,13 @@ struct cxd2820r_config { * Default: 0 * Values: 0, 1 */ - int if_agc_polarity:1; + bool if_agc_polarity; /* Spectrum inversion. * Default: 0 * Values: 0, 1 */ - int spec_inv:1; + bool spec_inv; /* IFs for all used modes. * Default: none, must set @@ -93,9 +93,6 @@ extern struct dvb_frontend *cxd2820r_attach( struct i2c_adapter *i2c, struct dvb_frontend *fe ); -extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter( - struct dvb_frontend *fe -); #else static inline struct dvb_frontend *cxd2820r_attach( const struct cxd2820r_config *config, @@ -106,12 +103,6 @@ static inline struct dvb_frontend *cxd2820r_attach( printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); return NULL; } -static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter( - struct dvb_frontend *fe -) -{ - return NULL; -} #endif diff --git a/drivers/media/dvb/frontends/cxd2820r_c.c b/drivers/media/dvb/frontends/cxd2820r_c.c index 3c07d40..b85f501 100644 --- a/drivers/media/dvb/frontends/cxd2820r_c.c +++ b/drivers/media/dvb/frontends/cxd2820r_c.c @@ -335,4 +335,3 @@ int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe, return 0; } - diff --git a/drivers/media/dvb/frontends/cxd2820r_core.c b/drivers/media/dvb/frontends/cxd2820r_core.c index 0779f69..036480f 100644 --- a/drivers/media/dvb/frontends/cxd2820r_core.c +++ b/drivers/media/dvb/frontends/cxd2820r_core.c @@ -314,6 +314,8 @@ static int cxd2820r_set_frontend(struct dvb_frontend *fe, } else if (c->delivery_system == SYS_DVBT2) { /* DVB-T => DVB-T2 */ ret = cxd2820r_sleep_t(fe); + if (ret) + break; ret = cxd2820r_set_frontend_t2(fe, p); } break; @@ -324,6 +326,8 @@ static int cxd2820r_set_frontend(struct dvb_frontend *fe, } else if (c->delivery_system == SYS_DVBT) { /* DVB-T2 => DVB-T */ ret = cxd2820r_sleep_t2(fe); + if (ret) + break; ret = cxd2820r_set_frontend_t(fe, p); } break; @@ -723,62 +727,22 @@ static void cxd2820r_release(struct dvb_frontend *fe) struct cxd2820r_priv *priv = fe->demodulator_priv; dbg("%s", __func__); - if (fe->ops.info.type == FE_OFDM) { - i2c_del_adapter(&priv->tuner_i2c_adapter); + if (fe->ops.info.type == FE_OFDM) kfree(priv); - } return; } -static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C; -} - -static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msg[], int num) -{ - struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap); - u8 obuf[msg[0].len + 2]; - struct i2c_msg msg2[2] = { - { - .addr = priv->cfg.i2c_address, - .flags = 0, - .len = sizeof(obuf), - .buf = obuf, - }, { - .addr = priv->cfg.i2c_address, - .flags = I2C_M_RD, - .len = msg[1].len, - .buf = msg[1].buf, - } - }; - - obuf[0] = 0x09; - obuf[1] = (msg[0].addr << 1); - if (num == 2) { /* I2C read */ - obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */ - msg2[0].len = sizeof(obuf) - 1; /* maybe HW bug ? */ - } - memcpy(&obuf[2], msg[0].buf, msg[0].len); - - return i2c_transfer(priv->i2c, msg2, num); -} - -static struct i2c_algorithm cxd2820r_tuner_i2c_algo = { - .master_xfer = cxd2820r_tuner_i2c_xfer, - .functionality = cxd2820r_tuner_i2c_func, -}; - -struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe) +static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) { struct cxd2820r_priv *priv = fe->demodulator_priv; - return &priv->tuner_i2c_adapter; + dbg("%s: %d", __func__, enable); + + /* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */ + return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1); } -EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter); -static struct dvb_frontend_ops cxd2820r_ops[2]; +static const struct dvb_frontend_ops cxd2820r_ops[2]; struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, struct i2c_adapter *i2c, struct dvb_frontend *fe) @@ -817,18 +781,6 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg, priv->fe[0].demodulator_priv = priv; priv->fe[1].demodulator_priv = priv; - /* create tuner i2c adapter */ - strlcpy(priv->tuner_i2c_adapter.name, - "CXD2820R tuner I2C adapter", - sizeof(priv->tuner_i2c_adapter.name)); - priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo; - priv->tuner_i2c_adapter.algo_data = NULL; - i2c_set_adapdata(&priv->tuner_i2c_adapter, priv); - if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) { - err("tuner I2C bus could not be initialized"); - goto error; - } - return &priv->fe[0]; } else { @@ -844,7 +796,7 @@ error: } EXPORT_SYMBOL(cxd2820r_attach); -static struct dvb_frontend_ops cxd2820r_ops[2] = { +static const struct dvb_frontend_ops cxd2820r_ops[2] = { { /* DVB-T/T2 */ .info = { @@ -869,6 +821,7 @@ static struct dvb_frontend_ops cxd2820r_ops[2] = { .sleep = cxd2820r_sleep, .get_tune_settings = cxd2820r_get_tune_settings, + .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl, .get_frontend = cxd2820r_get_frontend, @@ -897,6 +850,7 @@ static struct dvb_frontend_ops cxd2820r_ops[2] = { .sleep = cxd2820r_sleep, .get_tune_settings = cxd2820r_get_tune_settings, + .i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl, .set_frontend = cxd2820r_set_frontend, .get_frontend = cxd2820r_get_frontend, diff --git a/drivers/media/dvb/frontends/cxd2820r_priv.h b/drivers/media/dvb/frontends/cxd2820r_priv.h index 25adbee..9553913 100644 --- a/drivers/media/dvb/frontends/cxd2820r_priv.h +++ b/drivers/media/dvb/frontends/cxd2820r_priv.h @@ -50,18 +50,17 @@ struct cxd2820r_priv { struct i2c_adapter *i2c; struct dvb_frontend fe[2]; struct cxd2820r_config cfg; - struct i2c_adapter tuner_i2c_adapter; struct mutex fe_lock; /*Â FE lock */ int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */ - int ber_running:1; + bool ber_running; u8 bank[2]; u8 gpio[3]; fe_delivery_system_t delivery_system; - int last_tune_failed:1; /* for switch between T and T2 tune */ + bool last_tune_failed; /* for switch between T and T2 tune */ }; /* cxd2820r_core.c */ diff --git a/drivers/media/dvb/frontends/cxd2820r_t.c b/drivers/media/dvb/frontends/cxd2820r_t.c index 6582564..a04f9c8 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t.c +++ b/drivers/media/dvb/frontends/cxd2820r_t.c @@ -446,4 +446,3 @@ int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe, return 0; } - diff --git a/drivers/media/dvb/frontends/cxd2820r_t2.c b/drivers/media/dvb/frontends/cxd2820r_t2.c index c47b35c..6548588 100644 --- a/drivers/media/dvb/frontends/cxd2820r_t2.c +++ b/drivers/media/dvb/frontends/cxd2820r_t2.c @@ -420,4 +420,3 @@ int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe, return 0; } - diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h index ba91735..404f63a 100644 --- a/drivers/media/dvb/frontends/dib3000.h +++ b/drivers/media/dvb/frontends/dib3000.h @@ -17,7 +17,7 @@ * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver * sources, on which this driver (and the dvb-dibusb) are based. * - * see Documentation/dvb/README.dibusb for more information + * see Documentation/dvb/README.dvb-usb for more information * */ diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index e80c597..437904c 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c @@ -17,7 +17,7 @@ * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver * sources, on which this driver (and the dvb-dibusb) are based. * - * see Documentation/dvb/README.dibusb for more information + * see Documentation/dvb/README.dvb-usb for more information * */ diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 292bc19..ce8534f 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c @@ -1598,8 +1598,8 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap) return -ENOMEM; rx = kzalloc(2*sizeof(u8), GFP_KERNEL); if (!rx) { - goto rx_memory_error; ret = -ENOMEM; + goto rx_memory_error; } msg[0].buf = tx; @@ -2360,6 +2360,11 @@ struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, more common) */ st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; + /* FIXME: make sure the dev.parent field is initialized, or else + request_firmware() will hit an OOPS (this should be moved somewhere + more common) */ + st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent; + dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); /* init 7090 tuner adapter */ diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index fe284d5..a542db1 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c @@ -114,15 +114,10 @@ static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) return ret; } -static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) +static u16 __dib8000_read_word(struct dib8000_state *state, u16 reg) { u16 ret; - if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { - dprintk("could not acquire lock"); - return 0; - } - state->i2c_write_buffer[0] = reg >> 8; state->i2c_write_buffer[1] = reg & 0xff; @@ -140,6 +135,21 @@ static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) dprintk("i2c read error on %d", reg); ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; + + return ret; +} + +static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) +{ + u16 ret; + + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { + dprintk("could not acquire lock"); + return 0; + } + + ret = __dib8000_read_word(state, reg); + mutex_unlock(&state->i2c_buffer_lock); return ret; @@ -149,8 +159,15 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg) { u16 rw[2]; - rw[0] = dib8000_read_word(state, reg + 0); - rw[1] = dib8000_read_word(state, reg + 1); + if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) { + dprintk("could not acquire lock"); + return 0; + } + + rw[0] = __dib8000_read_word(state, reg + 0); + rw[1] = __dib8000_read_word(state, reg + 1); + + mutex_unlock(&state->i2c_buffer_lock); return ((rw[0] << 16) | (rw[1])); } diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c index b931074..660f806 100644 --- a/drivers/media/dvb/frontends/dib9000.c +++ b/drivers/media/dvb/frontends/dib9000.c @@ -1180,8 +1180,8 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p DibAcquireLock(&state->platform.risc.mem_mbx_lock); if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { - goto error; ret = -EIO; + goto error; } dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, @@ -2169,6 +2169,7 @@ static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) DibAcquireLock(&state->demod_lock); DibAcquireLock(&state->platform.risc.mem_mbx_lock); if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) { + DibReleaseLock(&state->platform.risc.mem_mbx_lock); ret = -EIO; goto error; } diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index 774d507..43be723 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c @@ -1,5 +1,6 @@ #include <linux/i2c.h> #include <linux/mutex.h> +#include <linux/module.h> #include "dibx000_common.h" diff --git a/drivers/media/dvb/frontends/drxd_hard.c b/drivers/media/dvb/frontends/drxd_hard.c index ea4c1c3..88e46f4 100644 --- a/drivers/media/dvb/frontends/drxd_hard.c +++ b/drivers/media/dvb/frontends/drxd_hard.c @@ -28,7 +28,6 @@ #include <linux/delay.h> #include <linux/firmware.h> #include <linux/i2c.h> -#include <linux/version.h> #include <asm/div64.h> #include "dvb_frontend.h" @@ -233,7 +232,7 @@ static int i2c_read(struct i2c_adapter *adap, return 0; } -inline u32 MulDiv32(u32 a, u32 b, u32 c) +static inline u32 MulDiv32(u32 a, u32 b, u32 c) { u64 tmp64; @@ -890,10 +889,15 @@ static int ReadIFAgc(struct drxd_state *state, u32 * pValue) u32 R2 = state->if_agc_cfg.R2; u32 R3 = state->if_agc_cfg.R3; - u32 Vmax = (3300 * R2) / (R1 + R2); - u32 Rpar = (R2 * R3) / (R3 + R2); - u32 Vmin = (3300 * Rpar) / (R1 + Rpar); - u32 Vout = Vmin + ((Vmax - Vmin) * Value) / 1024; + u32 Vmax, Rpar, Vmin, Vout; + + if (R2 == 0 && (R1 == 0 || R3 == 0)) + return 0; + + Vmax = (3300 * R2) / (R1 + R2); + Rpar = (R2 * R3) / (R3 + R2); + Vmin = (3300 * Rpar) / (R1 + Rpar); + Vout = Vmin + ((Vmax - Vmin) * Value) / 1024; *pValue = Vout; } @@ -910,14 +914,16 @@ static int load_firmware(struct drxd_state *state, const char *fw_name) return -EIO; } - state->microcode = kzalloc(fw->size, GFP_KERNEL); + state->microcode = kmalloc(fw->size, GFP_KERNEL); if (state->microcode == NULL) { - printk(KERN_ERR "drxd: firmware load failure: nomemory\n"); + release_firmware(fw); + printk(KERN_ERR "drxd: firmware load failure: no memory\n"); return -ENOMEM; } memcpy(state->microcode, fw->data, fw->size); state->microcode_length = fw->size; + release_firmware(fw); return 0; } @@ -925,16 +931,15 @@ static int DownloadMicrocode(struct drxd_state *state, const u8 *pMCImage, u32 Length) { u8 *pSrc; - u16 Flags; u32 Address; u16 nBlocks; u16 BlockSize; - u16 BlockCRC; u32 offset = 0; int i, status = 0; pSrc = (u8 *) pMCImage; - Flags = (pSrc[0] << 8) | pSrc[1]; + /* We're not using Flags */ + /* Flags = (pSrc[0] << 8) | pSrc[1]; */ pSrc += sizeof(u16); offset += sizeof(u16); nBlocks = (pSrc[0] << 8) | pSrc[1]; @@ -951,11 +956,13 @@ static int DownloadMicrocode(struct drxd_state *state, pSrc += sizeof(u16); offset += sizeof(u16); - Flags = (pSrc[0] << 8) | pSrc[1]; + /* We're not using Flags */ + /* u16 Flags = (pSrc[0] << 8) | pSrc[1]; */ pSrc += sizeof(u16); offset += sizeof(u16); - BlockCRC = (pSrc[0] << 8) | pSrc[1]; + /* We're not using BlockCRC */ + /* u16 BlockCRC = (pSrc[0] << 8) | pSrc[1]; */ pSrc += sizeof(u16); offset += sizeof(u16); diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c index 90bf573..2151c99 100644 --- a/drivers/media/dvb/frontends/ds3000.c +++ b/drivers/media/dvb/frontends/ds3000.c @@ -925,6 +925,13 @@ struct dvb_frontend *ds3000_attach(const struct ds3000_config *config, memcpy(&state->frontend.ops, &ds3000_ops, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; + + /* + * Some devices like T480 starts with voltage on. Be sure + * to turn voltage off during init, as this can otherwise + * interfere with Unicable SCR systems. + */ + ds3000_set_voltage(&state->frontend, SEC_VOLTAGE_OFF); return &state->frontend; error3: diff --git a/drivers/media/dvb/frontends/itd1000.c b/drivers/media/dvb/frontends/itd1000.c index f7a40a1..aa9ccb8 100644 --- a/drivers/media/dvb/frontends/itd1000.c +++ b/drivers/media/dvb/frontends/itd1000.c @@ -35,21 +35,18 @@ static int debug; module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); -#define deb(args...) do { \ +#define itd_dbg(args...) do { \ if (debug) { \ printk(KERN_DEBUG "ITD1000: " args);\ - printk("\n"); \ } \ } while (0) -#define warn(args...) do { \ +#define itd_warn(args...) do { \ printk(KERN_WARNING "ITD1000: " args); \ - printk("\n"); \ } while (0) -#define info(args...) do { \ +#define itd_info(args...) do { \ printk(KERN_INFO "ITD1000: " args); \ - printk("\n"); \ } while (0) /* don't write more than one byte with flexcop behind */ @@ -62,7 +59,7 @@ static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 le buf[0] = reg; memcpy(&buf[1], v, len); - /* deb("wr %02x: %02x", reg, v[0]); */ + /* itd_dbg("wr %02x: %02x\n", reg, v[0]); */ if (i2c_transfer(state->i2c, &msg, 1) != 1) { printk(KERN_WARNING "itd1000 I2C write failed\n"); @@ -83,7 +80,7 @@ static int itd1000_read_reg(struct itd1000_state *state, u8 reg) itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1); if (i2c_transfer(state->i2c, msg, 2) != 2) { - warn("itd1000 I2C read failed"); + itd_warn("itd1000 I2C read failed\n"); return -EREMOTEIO; } return val; @@ -127,14 +124,14 @@ static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate) u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0; u8 bw = itd1000_read_reg(state, BW) & 0xf0; - deb("symbol_rate = %d", symbol_rate); + itd_dbg("symbol_rate = %d\n", symbol_rate); /* not sure what is that ? - starting to download the table */ itd1000_write_reg(state, CON1, con1 | (1 << 1)); for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++) if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) { - deb("symrate: index: %d pgaext: %x, bbgvmin: %x", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin); + itd_dbg("symrate: index: %d pgaext: %x, bbgvmin: %x\n", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin); itd1000_write_reg(state, PLLFH, pllfh | (itd1000_lpf_pga[i].pgaext << 4)); itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin)); itd1000_write_reg(state, BW, bw | (i & 0x0f)); @@ -182,7 +179,7 @@ static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz) adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f; - deb("VCO: %dkHz: %d -> ADCOUT: %d %02x", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c); + itd_dbg("VCO: %dkHz: %d -> ADCOUT: %d %02x\n", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c); if (adcout > 13) { if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15)) @@ -232,7 +229,7 @@ static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz) pllf = (u32) tmp; state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF; - deb("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d", freq_khz, state->frequency, pllf, plln); + itd_dbg("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d\n", freq_khz, state->frequency, pllf, plln); itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */; itd1000_write_reg(state, PLLNL, plln & 0xff); @@ -242,7 +239,7 @@ static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz) for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) { if (freq_khz <= itd1000_fre_values[i].freq) { - deb("fre_values: %d", i); + itd_dbg("fre_values: %d\n", i); itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]); for (j = 0; j < 9; j++) itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]); @@ -382,7 +379,7 @@ struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter kfree(state); return NULL; } - info("successfully identified (ID: %d)", i); + itd_info("successfully identified (ID: %d)\n", i); memset(state->shadow, 0xff, sizeof(state->shadow)); for (i = 0x65; i < 0x9c; i++) diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a763ec75..6599b8f 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c @@ -50,7 +50,7 @@ static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data) if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1) dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret); - return (ret != 1) ? -EFAULT : 0; + return (ret != 1) ? -EIO : 0; } static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg) diff --git a/drivers/media/dvb/frontends/s5h1420.c b/drivers/media/dvb/frontends/s5h1420.c index 17f8cdf..507ccae 100644 --- a/drivers/media/dvb/frontends/s5h1420.c +++ b/drivers/media/dvb/frontends/s5h1420.c @@ -180,7 +180,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe, int result = 0; dprintk("enter %s\n", __func__); - if (cmd->msg_len > 8) + if (cmd->msg_len > sizeof(cmd->msg)) return -EINVAL; /* setup for DISEQC */ @@ -634,7 +634,7 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, struct s5h1420_state* state = fe->demodulator_priv; int frequency_delta; struct dvb_frontend_tune_settings fesettings; - uint8_t clock_settting; + uint8_t clock_setting; dprintk("enter %s\n", __func__); @@ -684,19 +684,19 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe, switch (state->fclk) { default: case 88000000: - clock_settting = 80; + clock_setting = 80; break; case 86000000: - clock_settting = 78; + clock_setting = 78; break; case 80000000: - clock_settting = 72; + clock_setting = 72; break; case 59000000: - clock_settting = 51; + clock_setting = 51; break; case 44000000: - clock_settting = 36; + clock_setting = 36; break; } dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32)); diff --git a/drivers/media/dvb/frontends/stb0899_algo.c b/drivers/media/dvb/frontends/stb0899_algo.c index d70eee0..117a569 100644 --- a/drivers/media/dvb/frontends/stb0899_algo.c +++ b/drivers/media/dvb/frontends/stb0899_algo.c @@ -358,6 +358,9 @@ static enum stb0899_status stb0899_check_data(struct stb0899_state *state) else dataTime = 500; + /* clear previous failed END_LOOPVIT */ + stb0899_read_reg(state, STB0899_VSTATUS); + stb0899_write_reg(state, STB0899_DSTATUS2, 0x00); /* force search loop */ while (1) { /* WARNING! VIT LOCKED has to be tested before VIT_END_LOOOP */ diff --git a/drivers/media/dvb/frontends/stb0899_drv.c b/drivers/media/dvb/frontends/stb0899_drv.c index 37a222d..8408ef8 100644 --- a/drivers/media/dvb/frontends/stb0899_drv.c +++ b/drivers/media/dvb/frontends/stb0899_drv.c @@ -706,7 +706,7 @@ static int stb0899_send_diseqc_msg(struct dvb_frontend *fe, struct dvb_diseqc_ma stb0899_write_reg(state, STB0899_DISCNTRL1, reg); for (i = 0; i < cmd->msg_len; i++) { /* wait for FIFO empty */ - if (stb0899_wait_diseqc_fifo_empty(state, 10) < 0) + if (stb0899_wait_diseqc_fifo_empty(state, 100) < 0) return -ETIMEDOUT; stb0899_write_reg(state, STB0899_DISFIFO, cmd->msg[i]); @@ -1426,9 +1426,9 @@ static void stb0899_set_iterations(struct stb0899_state *state) if (iter_scale > config->ldpc_max_iter) iter_scale = config->ldpc_max_iter; - reg = STB0899_READ_S2REG(STB0899_S2DEMOD, MAX_ITER); + reg = STB0899_READ_S2REG(STB0899_S2FEC, MAX_ITER); STB0899_SETFIELD_VAL(MAX_ITERATIONS, reg, iter_scale); - stb0899_write_s2reg(state, STB0899_S2DEMOD, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg); + stb0899_write_s2reg(state, STB0899_S2FEC, STB0899_BASE_MAX_ITER, STB0899_OFF0_MAX_ITER, reg); } static enum dvbfe_search stb0899_search(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c index 8e0cfad..0aa3962 100644 --- a/drivers/media/dvb/frontends/stv0288.c +++ b/drivers/media/dvb/frontends/stv0288.c @@ -127,6 +127,11 @@ static int stv0288_set_symbolrate(struct dvb_frontend *fe, u32 srate) if ((srate < 1000000) || (srate > 45000000)) return -EINVAL; + stv0288_writeregI(state, 0x22, 0); + stv0288_writeregI(state, 0x23, 0); + stv0288_writeregI(state, 0x2b, 0xff); + stv0288_writeregI(state, 0x2c, 0xf7); + temp = (unsigned int)srate / 1000; temp = temp * 32768; @@ -461,6 +466,7 @@ static int stv0288_set_frontend(struct dvb_frontend *fe, char tm; unsigned char tda[3]; + u8 reg, time_out = 0; dprintk("%s : FE_SET_FRONTEND\n", __func__); @@ -488,22 +494,29 @@ static int stv0288_set_frontend(struct dvb_frontend *fe, /* Carrier lock control register */ stv0288_writeregI(state, 0x15, 0xc5); - tda[0] = 0x2b; /* CFRM */ tda[2] = 0x0; /* CFRL */ - for (tm = -6; tm < 7;) { + for (tm = -9; tm < 7;) { /* Viterbi status */ - if (stv0288_readreg(state, 0x24) & 0x8) - break; - - tda[2] += 40; - if (tda[2] < 40) + reg = stv0288_readreg(state, 0x24); + if (reg & 0x8) + break; + if (reg & 0x80) { + time_out++; + if (time_out > 10) + break; + tda[2] += 40; + if (tda[2] < 40) + tm++; + } else { tm++; + tda[2] = 0; + time_out = 0; + } tda[1] = (unsigned char)tm; stv0288_writeregI(state, 0x2b, tda[1]); stv0288_writeregI(state, 0x2c, tda[2]); udelay(30); } - state->tuner_frequency = c->frequency; state->fec_inner = FEC_AUTO; state->symbol_rate = c->symbol_rate; diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index 52d8712..ebda419 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c @@ -3463,9 +3463,15 @@ static enum dvbfe_search stv090x_search(struct dvb_frontend *fe, struct dvb_fron static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) { struct stv090x_state *state = fe->demodulator_priv; - u32 reg; + u32 reg, dstatus; u8 search_state; + *status = 0; + + dstatus = STV090x_READ_DEMOD(state, DSTATUS); + if (STV090x_GETFIELD_Px(dstatus, CAR_LOCK_FIELD)) + *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER; + reg = STV090x_READ_DEMOD(state, DMDSTATE); search_state = STV090x_GETFIELD_Px(reg, HEADER_MODE_FIELD); @@ -3474,41 +3480,30 @@ static int stv090x_read_status(struct dvb_frontend *fe, enum fe_status *status) case 1: /* first PLH detected */ default: dprintk(FE_DEBUG, 1, "Status: Unlocked (Searching ..)"); - *status = 0; break; case 2: /* DVB-S2 mode */ dprintk(FE_DEBUG, 1, "Delivery system: DVB-S2"); - reg = STV090x_READ_DEMOD(state, DSTATUS); - if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { + if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { reg = STV090x_READ_DEMOD(state, PDELSTATUS1); if (STV090x_GETFIELD_Px(reg, PKTDELIN_LOCK_FIELD)) { + *status |= FE_HAS_VITERBI; reg = STV090x_READ_DEMOD(state, TSSTATUS); - if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - *status = FE_HAS_SIGNAL | - FE_HAS_CARRIER | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_LOCK; - } + if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) + *status |= FE_HAS_SYNC | FE_HAS_LOCK; } } break; case 3: /* DVB-S1/legacy mode */ dprintk(FE_DEBUG, 1, "Delivery system: DVB-S"); - reg = STV090x_READ_DEMOD(state, DSTATUS); - if (STV090x_GETFIELD_Px(reg, LOCK_DEFINITIF_FIELD)) { + if (STV090x_GETFIELD_Px(dstatus, LOCK_DEFINITIF_FIELD)) { reg = STV090x_READ_DEMOD(state, VSTATUSVIT); if (STV090x_GETFIELD_Px(reg, LOCKEDVIT_FIELD)) { + *status |= FE_HAS_VITERBI; reg = STV090x_READ_DEMOD(state, TSSTATUS); - if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) { - *status = FE_HAS_SIGNAL | - FE_HAS_CARRIER | - FE_HAS_VITERBI | - FE_HAS_SYNC | - FE_HAS_LOCK; - } + if (STV090x_GETFIELD_Px(reg, TSFIFO_LINEOK_FIELD)) + *status |= FE_HAS_SYNC | FE_HAS_LOCK; } } break; diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c index 93f6a75..7f10594 100644 --- a/drivers/media/dvb/frontends/tda10048.c +++ b/drivers/media/dvb/frontends/tda10048.c @@ -206,15 +206,16 @@ static struct init_tab { static struct pll_tab { u32 clk_freq_khz; u32 if_freq_khz; - u8 m, n, p; } pll_tab[] = { - { TDA10048_CLK_4000, TDA10048_IF_36130, 10, 0, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_3300, 10, 3, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_3500, 10, 3, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_3800, 10, 3, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_4000, 10, 3, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_4300, 10, 3, 0 }, - { TDA10048_CLK_16000, TDA10048_IF_36130, 10, 3, 0 }, + { TDA10048_CLK_4000, TDA10048_IF_36130 }, + { TDA10048_CLK_16000, TDA10048_IF_3300 }, + { TDA10048_CLK_16000, TDA10048_IF_3500 }, + { TDA10048_CLK_16000, TDA10048_IF_3800 }, + { TDA10048_CLK_16000, TDA10048_IF_4000 }, + { TDA10048_CLK_16000, TDA10048_IF_4300 }, + { TDA10048_CLK_16000, TDA10048_IF_4500 }, + { TDA10048_CLK_16000, TDA10048_IF_5000 }, + { TDA10048_CLK_16000, TDA10048_IF_36130 }, }; static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data) @@ -460,9 +461,6 @@ static int tda10048_set_if(struct dvb_frontend *fe, enum fe_bandwidth bw) state->freq_if_hz = pll_tab[i].if_freq_khz * 1000; state->xtal_hz = pll_tab[i].clk_freq_khz * 1000; - state->pll_mfactor = pll_tab[i].m; - state->pll_nfactor = pll_tab[i].n; - state->pll_pfactor = pll_tab[i].p; break; } } @@ -781,6 +779,10 @@ static int tda10048_init(struct dvb_frontend *fe) dprintk(1, "%s()\n", __func__); + /* PLL */ + init_tab[4].data = (u8)(state->pll_mfactor); + init_tab[5].data = (u8)(state->pll_nfactor) | 0x40; + /* Apply register defaults */ for (i = 0; i < ARRAY_SIZE(init_tab); i++) tda10048_writereg(state, init_tab[i].reg, init_tab[i].data); @@ -1123,7 +1125,7 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, /* setup the state and clone the config */ memcpy(&state->config, config, sizeof(*config)); state->i2c = i2c; - state->fwloaded = 0; + state->fwloaded = config->no_firmware; state->bandwidth = BANDWIDTH_8_MHZ; /* check if the demod is present */ @@ -1135,6 +1137,17 @@ struct dvb_frontend *tda10048_attach(const struct tda10048_config *config, sizeof(struct dvb_frontend_ops)); state->frontend.demodulator_priv = state; + /* set pll */ + if (config->set_pll) { + state->pll_mfactor = config->pll_m; + state->pll_nfactor = config->pll_n; + state->pll_pfactor = config->pll_p; + } else { + state->pll_mfactor = 10; + state->pll_nfactor = 3; + state->pll_pfactor = 0; + } + /* Establish any defaults the the user didn't pass */ tda10048_establish_defaults(&state->frontend); diff --git a/drivers/media/dvb/frontends/tda10048.h b/drivers/media/dvb/frontends/tda10048.h index 8828cea..fb2ef5a 100644 --- a/drivers/media/dvb/frontends/tda10048.h +++ b/drivers/media/dvb/frontends/tda10048.h @@ -51,6 +51,7 @@ struct tda10048_config { #define TDA10048_IF_4300 4300 #define TDA10048_IF_4500 4500 #define TDA10048_IF_4750 4750 +#define TDA10048_IF_5000 5000 #define TDA10048_IF_36130 36130 u16 dtv6_if_freq_khz; u16 dtv7_if_freq_khz; @@ -62,6 +63,13 @@ struct tda10048_config { /* Disable I2C gate access */ u8 disable_gate_access; + + bool no_firmware; + + bool set_pll; + u8 pll_m; + u8 pll_p; + u8 pll_n; }; #if defined(CONFIG_DVB_TDA10048) || \ diff --git a/drivers/media/dvb/mantis/Makefile b/drivers/media/dvb/mantis/Makefile index 98dc5cd..ec8116d 100644 --- a/drivers/media/dvb/mantis/Makefile +++ b/drivers/media/dvb/mantis/Makefile @@ -25,4 +25,4 @@ obj-$(CONFIG_MANTIS_CORE) += mantis_core.o obj-$(CONFIG_DVB_MANTIS) += mantis.o obj-$(CONFIG_DVB_HOPPER) += hopper.o -EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c index 1402062..71622f6 100644 --- a/drivers/media/dvb/mantis/hopper_cards.c +++ b/drivers/media/dvb/mantis/hopper_cards.c @@ -65,7 +65,7 @@ static int devs; static irqreturn_t hopper_irq_handler(int irq, void *dev_id) { - u32 stat = 0, mask = 0, lstat = 0, mstat = 0; + u32 stat = 0, mask = 0, lstat = 0; u32 rst_stat = 0, rst_mask = 0; struct mantis_pci *mantis; @@ -80,7 +80,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) stat = mmread(MANTIS_INT_STAT); mask = mmread(MANTIS_INT_MASK); - mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; + lstat = stat & ~MANTIS_INT_RISCSTAT; if (!(stat & mask)) return IRQ_NONE; @@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id) } if (stat & MANTIS_INT_RISCI) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); - mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; + mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; tasklet_schedule(&mantis->tasklet); } if (stat & MANTIS_INT_I2CDONE) { diff --git a/drivers/media/dvb/mantis/mantis_ca.c b/drivers/media/dvb/mantis/mantis_ca.c index 330216f..3d70469 100644 --- a/drivers/media/dvb/mantis/mantis_ca.c +++ b/drivers/media/dvb/mantis/mantis_ca.c @@ -22,6 +22,7 @@ #include <linux/slab.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c index 05cbb9d..c2bb90b 100644 --- a/drivers/media/dvb/mantis/mantis_cards.c +++ b/drivers/media/dvb/mantis/mantis_cards.c @@ -73,7 +73,7 @@ static char *label[10] = { static irqreturn_t mantis_irq_handler(int irq, void *dev_id) { - u32 stat = 0, mask = 0, lstat = 0, mstat = 0; + u32 stat = 0, mask = 0, lstat = 0; u32 rst_stat = 0, rst_mask = 0; struct mantis_pci *mantis; @@ -88,7 +88,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id) stat = mmread(MANTIS_INT_STAT); mask = mmread(MANTIS_INT_MASK); - mstat = lstat = stat & ~MANTIS_INT_RISCSTAT; + lstat = stat & ~MANTIS_INT_RISCSTAT; if (!(stat & mask)) return IRQ_NONE; @@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id) } if (stat & MANTIS_INT_RISCI) { dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); - mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; + mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28; tasklet_schedule(&mantis->tasklet); } if (stat & MANTIS_INT_I2CDONE) { diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h index bd400d2..f2410cf 100644 --- a/drivers/media/dvb/mantis/mantis_common.h +++ b/drivers/media/dvb/mantis/mantis_common.h @@ -21,6 +21,7 @@ #ifndef __MANTIS_COMMON_H #define __MANTIS_COMMON_H +#include <linux/interrupt.h> #include <linux/mutex.h> #include <linux/workqueue.h> @@ -122,11 +123,8 @@ struct mantis_pci { unsigned int num; /* RISC Core */ - u32 finished_block; + u32 busy_block; u32 last_block; - u32 line_bytes; - u32 line_count; - u32 risc_pos; u8 *buf_cpu; dma_addr_t buf_dma; u32 *risc_cpu; diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c index 46202a4..c61ca7d 100644 --- a/drivers/media/dvb/mantis/mantis_dma.c +++ b/drivers/media/dvb/mantis/mantis_dma.c @@ -43,13 +43,17 @@ #define RISC_IRQ (0x01 << 24) #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) -#define RISC_FLUSH() (mantis->risc_pos = 0) -#define RISC_INSTR(opcode) (mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode)) +#define RISC_FLUSH(risc_pos) (risc_pos = 0) +#define RISC_INSTR(risc_pos, opcode) (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode)) #define MANTIS_BUF_SIZE (64 * 1024) -#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE >> 4) -#define MANTIS_BLOCK_COUNT (1 << 4) -#define MANTIS_RISC_SIZE PAGE_SIZE +#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE / 4) +#define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */ +#define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES) + +#define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES) +/* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */ +#define MANTIS_RISC_SIZE PAGE_SIZE /* RISC program must fit here. */ int mantis_dma_exit(struct mantis_pci *mantis) { @@ -124,27 +128,6 @@ err: return -ENOMEM; } -static inline int mantis_calc_lines(struct mantis_pci *mantis) -{ - mantis->line_bytes = MANTIS_BLOCK_BYTES; - mantis->line_count = MANTIS_BLOCK_COUNT; - - while (mantis->line_bytes > 4095) { - mantis->line_bytes >>= 1; - mantis->line_count <<= 1; - } - - dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]", - MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count); - - if (mantis->line_count > 255) { - dprintk(MANTIS_ERROR, 1, "Buffer size error"); - return -EINVAL; - } - - return 0; -} - int mantis_dma_init(struct mantis_pci *mantis) { int err = 0; @@ -158,12 +141,6 @@ int mantis_dma_init(struct mantis_pci *mantis) goto err; } - err = mantis_calc_lines(mantis); - if (err < 0) { - dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed"); - - goto err; - } return 0; err: @@ -174,31 +151,32 @@ EXPORT_SYMBOL_GPL(mantis_dma_init); static inline void mantis_risc_program(struct mantis_pci *mantis) { u32 buf_pos = 0; - u32 line; + u32 line, step; + u32 risc_pos; dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); - RISC_FLUSH(); - - dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u", - mantis->line_count, mantis->line_bytes); - - for (line = 0; line < mantis->line_count; line++) { - dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line); - if (!(buf_pos % MANTIS_BLOCK_BYTES)) { - RISC_INSTR(RISC_WRITE | - RISC_IRQ | - RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) + - (MANTIS_BLOCK_COUNT - 1)) % - MANTIS_BLOCK_COUNT) | - mantis->line_bytes); - } else { - RISC_INSTR(RISC_WRITE | mantis->line_bytes); - } - RISC_INSTR(mantis->buf_dma + buf_pos); - buf_pos += mantis->line_bytes; + RISC_FLUSH(risc_pos); + + dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u", + MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES); + + for (line = 0; line < MANTIS_BLOCK_COUNT; line++) { + for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) { + dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step); + if (step == 0) { + RISC_INSTR(risc_pos, RISC_WRITE | + RISC_IRQ | + RISC_STATUS(line) | + MANTIS_DMA_TR_BYTES); + } else { + RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES); + } + RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos); + buf_pos += MANTIS_DMA_TR_BYTES; + } } - RISC_INSTR(RISC_JUMP); - RISC_INSTR(mantis->risc_dma); + RISC_INSTR(risc_pos, RISC_JUMP); + RISC_INSTR(risc_pos, mantis->risc_dma); } void mantis_dma_start(struct mantis_pci *mantis) @@ -210,7 +188,7 @@ void mantis_dma_start(struct mantis_pci *mantis) mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); mmwrite(0, MANTIS_DMA_CTL); - mantis->last_block = mantis->finished_block = 0; + mantis->last_block = mantis->busy_block = 0; mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); @@ -245,9 +223,9 @@ void mantis_dma_xfer(unsigned long data) struct mantis_pci *mantis = (struct mantis_pci *) data; struct mantis_hwconfig *config = mantis->hwconfig; - while (mantis->last_block != mantis->finished_block) { + while (mantis->last_block != mantis->busy_block) { dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", - mantis->last_block, mantis->finished_block); + mantis->last_block, mantis->busy_block); (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); diff --git a/drivers/media/dvb/mantis/mantis_evm.c b/drivers/media/dvb/mantis/mantis_evm.c index 9f73c2c..36f2256 100644 --- a/drivers/media/dvb/mantis/mantis_evm.c +++ b/drivers/media/dvb/mantis/mantis_evm.c @@ -23,6 +23,7 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_hif.c b/drivers/media/dvb/mantis/mantis_hif.c index 5772ebb..672cf4d 100644 --- a/drivers/media/dvb/mantis/mantis_hif.c +++ b/drivers/media/dvb/mantis/mantis_hif.c @@ -23,6 +23,7 @@ #include <linux/sched.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_ioc.c b/drivers/media/dvb/mantis/mantis_ioc.c index 479086d..24fcdc6 100644 --- a/drivers/media/dvb/mantis/mantis_ioc.c +++ b/drivers/media/dvb/mantis/mantis_ioc.c @@ -24,6 +24,7 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_pcmcia.c b/drivers/media/dvb/mantis/mantis_pcmcia.c index 5cb545b..2f188c0 100644 --- a/drivers/media/dvb/mantis/mantis_pcmcia.c +++ b/drivers/media/dvb/mantis/mantis_pcmcia.c @@ -23,6 +23,7 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_uart.c b/drivers/media/dvb/mantis/mantis_uart.c index f807c8b..18340da 100644 --- a/drivers/media/dvb/mantis/mantis_uart.c +++ b/drivers/media/dvb/mantis/mantis_uart.c @@ -20,6 +20,7 @@ #include <linux/kernel.h> #include <linux/spinlock.h> +#include <asm/io.h> #include <linux/signal.h> #include <linux/sched.h> diff --git a/drivers/media/dvb/mantis/mantis_vp1034.c b/drivers/media/dvb/mantis/mantis_vp1034.c index 26bc0cb..430ae84 100644 --- a/drivers/media/dvb/mantis/mantis_vp1034.c +++ b/drivers/media/dvb/mantis/mantis_vp1034.c @@ -21,6 +21,7 @@ #include <linux/signal.h> #include <linux/sched.h> #include <linux/interrupt.h> +#include <asm/io.h> #include "dmxdev.h" #include "dvbdev.h" diff --git a/drivers/media/dvb/mantis/mantis_vp1041.c b/drivers/media/dvb/mantis/mantis_vp1041.c index 38a436c..07aa887 100644 --- a/drivers/media/dvb/mantis/mantis_vp1041.c +++ b/drivers/media/dvb/mantis/mantis_vp1041.c @@ -51,7 +51,6 @@ static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = { { STB0899_DISRX_ST0 , 0x04 }, { STB0899_DISRX_ST1 , 0x00 }, { STB0899_DISPARITY , 0x00 }, - { STB0899_DISFIFO , 0x00 }, { STB0899_DISSTATUS , 0x20 }, { STB0899_DISF22 , 0x99 }, { STB0899_DISF22RX , 0xa8 }, diff --git a/drivers/media/dvb/ngene/Kconfig b/drivers/media/dvb/ngene/Kconfig index cec242b..64c8470 100644 --- a/drivers/media/dvb/ngene/Kconfig +++ b/drivers/media/dvb/ngene/Kconfig @@ -5,6 +5,8 @@ config DVB_NGENE select DVB_STV6110x if !DVB_FE_CUSTOMISE select DVB_STV090x if !DVB_FE_CUSTOMISE select DVB_LGDT330X if !DVB_FE_CUSTOMISE + select DVB_DRXK if !DVB_FE_CUSTOMISE + select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE ---help--- Support for Micronas PCI express cards with nGene bridge. diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile index 2bc9687..13ebeff 100644 --- a/drivers/media/dvb/ngene/Makefile +++ b/drivers/media/dvb/ngene/Makefile @@ -6,9 +6,9 @@ ngene-objs := ngene-core.o ngene-i2c.o ngene-cards.o ngene-dvb.o obj-$(CONFIG_DVB_NGENE) += ngene.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ -EXTRA_CFLAGS += -Idrivers/media/common/tuners/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ +ccflags-y += -Idrivers/media/dvb/frontends/ +ccflags-y += -Idrivers/media/common/tuners/ # For the staging CI driver cxd2099 -EXTRA_CFLAGS += -Idrivers/staging/cxd2099/ +ccflags-y += -Idrivers/staging/media/cxd2099/ diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index fcf4be9..0564192 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -40,6 +40,8 @@ #include "lnbh24.h" #include "lgdt330x.h" #include "mt2131.h" +#include "tda18271c2dd.h" +#include "drxk.h" /****************************************************************************/ @@ -83,6 +85,49 @@ static int tuner_attach_stv6110(struct ngene_channel *chan) } +static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct ngene_channel *chan = fe->sec_priv; + int status; + + if (enable) { + down(&chan->dev->pll_mutex); + status = chan->gate_ctrl(fe, 1); + } else { + status = chan->gate_ctrl(fe, 0); + up(&chan->dev->pll_mutex); + } + return status; +} + +static int tuner_attach_tda18271(struct ngene_channel *chan) +{ + struct i2c_adapter *i2c; + struct dvb_frontend *fe; + + i2c = &chan->dev->channel[0].i2c_adapter; + if (chan->fe->ops.i2c_gate_ctrl) + chan->fe->ops.i2c_gate_ctrl(chan->fe, 1); + fe = dvb_attach(tda18271c2dd_attach, chan->fe, i2c, 0x60); + if (chan->fe->ops.i2c_gate_ctrl) + chan->fe->ops.i2c_gate_ctrl(chan->fe, 0); + if (!fe) { + printk(KERN_ERR "No TDA18271 found!\n"); + return -ENODEV; + } + + return 0; +} + +static int tuner_attach_probe(struct ngene_channel *chan) +{ + if (chan->demod_type == 0) + return tuner_attach_stv6110(chan); + if (chan->demod_type == 1) + return tuner_attach_tda18271(chan); + return -EINVAL; +} + static int demod_attach_stv0900(struct ngene_channel *chan) { struct i2c_adapter *i2c; @@ -130,6 +175,60 @@ static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock) up(&chan->dev->pll_mutex); } +static int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) +{ + struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, + .buf = val, .len = 1 } }; + return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; +} + +static int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, + u16 reg, u8 *val) +{ + u8 msg[2] = {reg>>8, reg&0xff}; + struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, + .buf = msg, .len = 2}, + {.addr = adr, .flags = I2C_M_RD, + .buf = val, .len = 1} }; + return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; +} + +static int port_has_stv0900(struct i2c_adapter *i2c, int port) +{ + u8 val; + if (i2c_read_reg16(i2c, 0x68+port/2, 0xf100, &val) < 0) + return 0; + return 1; +} + +static int port_has_drxk(struct i2c_adapter *i2c, int port) +{ + u8 val; + + if (i2c_read(i2c, 0x29+port, &val) < 0) + return 0; + return 1; +} + +static int demod_attach_drxk(struct ngene_channel *chan, + struct i2c_adapter *i2c) +{ + struct drxk_config config; + + memset(&config, 0, sizeof(config)); + config.adr = 0x29 + (chan->number ^ 2); + + chan->fe = dvb_attach(drxk_attach, &config, i2c, &chan->fe2); + if (!chan->fe) { + printk(KERN_ERR "No DRXK found!\n"); + return -ENODEV; + } + chan->fe->sec_priv = chan; + chan->gate_ctrl = chan->fe->ops.i2c_gate_ctrl; + chan->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; + return 0; +} + static int cineS2_probe(struct ngene_channel *chan) { struct i2c_adapter *i2c; @@ -144,43 +243,42 @@ static int cineS2_probe(struct ngene_channel *chan) else i2c = &chan->dev->channel[1].i2c_adapter; - fe_conf = chan->dev->card_info->fe_config[chan->number]; - i2c_msg.addr = fe_conf->address; - - /* probe demod */ - i2c_msg.len = 2; - buf[0] = 0xf1; - buf[1] = 0x00; - rc = i2c_transfer(i2c, &i2c_msg, 1); - if (rc != 1) - return -ENODEV; - - /* demod found, attach it */ - rc = demod_attach_stv0900(chan); - if (rc < 0 || chan->number < 2) - return rc; - - /* demod #2: reprogram outputs DPN1 & DPN2 */ - i2c_msg.len = 3; - buf[0] = 0xf1; - switch (chan->number) { - case 2: - buf[1] = 0x5c; - buf[2] = 0xc2; - break; - case 3: - buf[1] = 0x61; - buf[2] = 0xcc; - break; - default: + if (port_has_stv0900(i2c, chan->number)) { + chan->demod_type = 0; + fe_conf = chan->dev->card_info->fe_config[chan->number]; + /* demod found, attach it */ + rc = demod_attach_stv0900(chan); + if (rc < 0 || chan->number < 2) + return rc; + + /* demod #2: reprogram outputs DPN1 & DPN2 */ + i2c_msg.addr = fe_conf->address; + i2c_msg.len = 3; + buf[0] = 0xf1; + switch (chan->number) { + case 2: + buf[1] = 0x5c; + buf[2] = 0xc2; + break; + case 3: + buf[1] = 0x61; + buf[2] = 0xcc; + break; + default: + return -ENODEV; + } + rc = i2c_transfer(i2c, &i2c_msg, 1); + if (rc != 1) { + printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); + return -EIO; + } + } else if (port_has_drxk(i2c, chan->number^2)) { + chan->demod_type = 1; + demod_attach_drxk(chan, i2c); + } else { + printk(KERN_ERR "No demod found on chan %d\n", chan->number); return -ENODEV; } - rc = i2c_transfer(i2c, &i2c_msg, 1); - if (rc != 1) { - printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n"); - return -EIO; - } - return 0; } @@ -306,7 +404,7 @@ static struct ngene_info ngene_info_satixS2v2 = { .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSOUT}, .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe}, - .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110}, + .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe}, .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, .lnb = {0x0a, 0x08, 0x0b, 0x09}, @@ -321,7 +419,7 @@ static struct ngene_info ngene_info_cineS2v5 = { .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSOUT}, .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe}, - .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110}, + .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_probe, tuner_attach_probe}, .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, .lnb = {0x0a, 0x08, 0x0b, 0x09}, @@ -331,13 +429,13 @@ static struct ngene_info ngene_info_cineS2v5 = { }; -static struct ngene_info ngene_info_duoFlexS2 = { +static struct ngene_info ngene_info_duoFlex = { .type = NGENE_SIDEWINDER, - .name = "Digital Devices DuoFlex S2 miniPCIe", + .name = "Digital Devices DuoFlex PCIe or miniPCIe", .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSOUT}, .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe}, - .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110}, + .tuner_attach = {tuner_attach_probe, tuner_attach_probe, tuner_attach_probe, tuner_attach_probe}, .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2}, .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1}, .lnb = {0x0a, 0x08, 0x0b, 0x09}, @@ -385,8 +483,8 @@ static const struct pci_device_id ngene_id_tbl[] __devinitdata = { NGENE_ID(0x18c3, 0xdb01, ngene_info_satixS2), NGENE_ID(0x18c3, 0xdb02, ngene_info_satixS2v2), NGENE_ID(0x18c3, 0xdd00, ngene_info_cineS2v5), - NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlexS2), - NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlexS2), + NGENE_ID(0x18c3, 0xdd10, ngene_info_duoFlex), + NGENE_ID(0x18c3, 0xdd20, ngene_info_duoFlex), NGENE_ID(0x1461, 0x062e, ngene_info_m780), {0} }; diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c index 6927c72..f129a93 100644 --- a/drivers/media/dvb/ngene/ngene-core.c +++ b/drivers/media/dvb/ngene/ngene-core.c @@ -41,7 +41,7 @@ #include "ngene.h" -static int one_adapter = 1; +static int one_adapter; module_param(one_adapter, int, 0444); MODULE_PARM_DESC(one_adapter, "Use only one adapter."); @@ -461,7 +461,7 @@ static u8 TSFeatureDecoderSetup[8 * 5] = { 0x42, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, 0x40, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXH */ 0x71, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* DRXHser */ - 0x72, 0x06, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */ + 0x72, 0x00, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* S2ser */ 0x40, 0x07, 0x00, 0x02, 0x02, 0xbc, 0x00, 0x00, /* LGDT3303 */ }; @@ -507,7 +507,7 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags) { u32 *ptr = Buffer; - memset(Buffer, 0xff, Length); + memset(Buffer, TS_FILLER, Length); while (Length > 0) { if (Flags & DF_SWAP32) *ptr = 0x471FFF10; @@ -1443,6 +1443,9 @@ static void release_channel(struct ngene_channel *chan) chan->ci_dev = NULL; } + if (chan->fe2) + dvb_unregister_frontend(chan->fe2); + if (chan->fe) { dvb_unregister_frontend(chan->fe); dvb_frontend_detach(chan->fe); @@ -1534,6 +1537,14 @@ static int init_channel(struct ngene_channel *chan) goto err; chan->has_demux = true; } + if (chan->fe2) { + if (dvb_register_frontend(adapter, chan->fe2) < 0) + goto err; + chan->fe2->tuner_priv = chan->fe->tuner_priv; + memcpy(&chan->fe2->ops.tuner_ops, + &chan->fe->ops.tuner_ops, + sizeof(struct dvb_tuner_ops)); + } if (chan->has_demux) { ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", @@ -1571,11 +1582,18 @@ static int init_channels(struct ngene *dev) return 0; } +static struct cxd2099_cfg cxd_cfg = { + .bitrate = 62000, + .adr = 0x40, + .polarity = 0, + .clock_mode = 0, +}; + static void cxd_attach(struct ngene *dev) { struct ngene_ci *ci = &dev->ci; - ci->en = cxd2099_attach(0x40, dev, &dev->channel[0].i2c_adapter); + ci->en = cxd2099_attach(&cxd_cfg, dev, &dev->channel[0].i2c_adapter); ci->dev = dev; return; } diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c index 0b49432..fcb16a6 100644 --- a/drivers/media/dvb/ngene/ngene-dvb.c +++ b/drivers/media/dvb/ngene/ngene-dvb.c @@ -118,6 +118,16 @@ static void swap_buffer(u32 *p, u32 len) } } +/* start of filler packet */ +static u8 fill_ts[] = { 0x47, 0x1f, 0xff, 0x10, TS_FILLER }; + +/* #define DEBUG_CI_XFER */ +#ifdef DEBUG_CI_XFER +static u32 ok; +static u32 overflow; +static u32 stripped; +#endif + void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; @@ -126,21 +136,41 @@ void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) if (flags & DF_SWAP32) swap_buffer(buf, len); + if (dev->ci.en && chan->number == 2) { - if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) { - dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len); - wake_up_interruptible(&dev->tsin_rbuf.queue); + while (len >= 188) { + if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) { + if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) { + dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188); + wake_up(&dev->tsin_rbuf.queue); +#ifdef DEBUG_CI_XFER + ok++; +#endif + } +#ifdef DEBUG_CI_XFER + else + overflow++; +#endif + } +#ifdef DEBUG_CI_XFER + else + stripped++; + + if (ok % 100 == 0 && overflow) + printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped); +#endif + buf += 188; + len -= 188; } - return 0; + return NULL; } - if (chan->users > 0) { + + if (chan->users > 0) dvb_dmx_swfilter(&chan->demux, buf, len); - } + return NULL; } -u8 fill_ts[188] = { 0x47, 0x1f, 0xff, 0x10 }; - void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h index 40fce9e..5443dc0 100644 --- a/drivers/media/dvb/ngene/ngene.h +++ b/drivers/media/dvb/ngene/ngene.h @@ -641,8 +641,11 @@ struct ngene_channel { int mode; bool has_adapter; bool has_demux; + int demod_type; + int (*gate_ctrl)(struct dvb_frontend *, int); struct dvb_frontend *fe; + struct dvb_frontend *fe2; struct dmxdev dmxdev; struct dvb_demux demux; struct dvb_net dvbnet; @@ -786,6 +789,8 @@ struct ngene { u8 uart_rbuf[UART_RBUF_LEN]; int uart_rp, uart_wp; +#define TS_FILLER 0x6f + u8 *tsout_buf; #define TSOUT_BUF_SIZE (512*188*8) struct dvb_ringbuffer tsout_rbuf; @@ -852,7 +857,7 @@ struct ngene_info { }; #ifdef NGENE_V4L -struct ngene_format{ +struct ngene_format { char *name; int fourcc; /* video4linux 2 */ int btformat; /* BT848_COLOR_FMT_* */ diff --git a/drivers/media/dvb/pluto2/Makefile b/drivers/media/dvb/pluto2/Makefile index 7ac1287..7008223 100644 --- a/drivers/media/dvb/pluto2/Makefile +++ b/drivers/media/dvb/pluto2/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_DVB_PLUTO2) += pluto2.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c index 7cb79ec..80fb510 100644 --- a/drivers/media/dvb/pluto2/pluto2.c +++ b/drivers/media/dvb/pluto2/pluto2.c @@ -26,6 +26,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> #include <linux/init.h> +#include <linux/interrupt.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/dvb/pt1/Makefile index a66da17..d80d8e8 100644 --- a/drivers/media/dvb/pt1/Makefile +++ b/drivers/media/dvb/pt1/Makefile @@ -2,4 +2,4 @@ earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o obj-$(CONFIG_DVB_PT1) += earth-pt1.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -Idrivers/media/dvb/frontends +ccflags-y += -Idrivers/media/dvb/dvb-core -Idrivers/media/dvb/frontends diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile index c54140b..f233b57 100644 --- a/drivers/media/dvb/siano/Makefile +++ b/drivers/media/dvb/siano/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o obj-$(CONFIG_SMS_USB_DRV) += smsusb.o obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core +ccflags-y += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m) +ccflags-y += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c index af121db..680c781 100644 --- a/drivers/media/dvb/siano/sms-cards.c +++ b/drivers/media/dvb/siano/sms-cards.c @@ -19,6 +19,7 @@ #include "sms-cards.h" #include "smsir.h" +#include <linux/module.h> static int sms_dbg; module_param_named(cards_dbg, sms_dbg, int, 0644); diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c index 78765ed..7331e84 100644 --- a/drivers/media/dvb/siano/smscoreapi.c +++ b/drivers/media/dvb/siano/smscoreapi.c @@ -1147,7 +1147,7 @@ static int smscore_validate_client(struct smscore_device_t *coredev, if (!client) { sms_err("bad parameter."); - return -EFAULT; + return -EINVAL; } registered_client = smscore_find_client(coredev, data_type, id); if (registered_client == client) diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h index 8ecadec..c592ae0 100644 --- a/drivers/media/dvb/siano/smscoreapi.h +++ b/drivers/media/dvb/siano/smscoreapi.h @@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #ifndef __SMS_CORE_API_H__ #define __SMS_CORE_API_H__ -#include <linux/version.h> #include <linux/device.h> #include <linux/list.h> #include <linux/mm.h> diff --git a/drivers/media/dvb/siano/smsendian.c b/drivers/media/dvb/siano/smsendian.c index 457b6d0..e2657c2 100644 --- a/drivers/media/dvb/siano/smsendian.c +++ b/drivers/media/dvb/siano/smsendian.c @@ -19,6 +19,7 @@ ****************************************************************/ +#include <linux/export.h> #include <asm/byteorder.h> #include "smsendian.h" diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c index e57d38b..91f8c82 100644 --- a/drivers/media/dvb/siano/smssdio.c +++ b/drivers/media/dvb/siano/smssdio.c @@ -39,6 +39,7 @@ #include <linux/mmc/card.h> #include <linux/mmc/sdio_func.h> #include <linux/mmc/sdio_ids.h> +#include <linux/module.h> #include "smscoreapi.h" #include "sms-cards.h" diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 3d2867d..027550d 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c @@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #include <linux/usb.h> #include <linux/firmware.h> #include <linux/slab.h> +#include <linux/module.h> #include "smscoreapi.h" #include "sms-cards.h" diff --git a/drivers/media/dvb/ttpci/Makefile b/drivers/media/dvb/ttpci/Makefile index 8a4d5bb..f6e8693 100644 --- a/drivers/media/dvb/ttpci/Makefile +++ b/drivers/media/dvb/ttpci/Makefile @@ -17,5 +17,5 @@ obj-$(CONFIG_DVB_BUDGET_CI) += budget-ci.o obj-$(CONFIG_DVB_BUDGET_PATCH) += budget-patch.o obj-$(CONFIG_DVB_AV7110) += dvb-ttpci.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ -EXTRA_CFLAGS += -Idrivers/media/common/tuners +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ +ccflags-y += -Idrivers/media/common/tuners diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index cdd31ca..ee8ee1d 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c @@ -25,6 +25,8 @@ * the project's page is at http://www.linuxtv.org/ */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include <linux/kernel.h> #include <linux/types.h> #include <linux/delay.h> @@ -253,7 +255,7 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) switch (av7110->current_input) { case 1: - dprintk(1, "switching SAA7113 to Analog Tuner Input.\n"); + dprintk(1, "switching SAA7113 to Analog Tuner Input\n"); msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0000); // loudspeaker source msp_writereg(av7110, MSP_WR_DSP, 0x0009, 0x0000); // headphone source msp_writereg(av7110, MSP_WR_DSP, 0x000a, 0x0000); // SCART 1 source @@ -263,7 +265,7 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { if (ves1820_writereg(dev, 0x09, 0x0f, 0x60)) - dprintk(1, "setting band in demodulator failed.\n"); + dprintk(1, "setting band in demodulator failed\n"); } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // TDA9819 pin9(STD) saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTHI); // TDA9819 pin30(VIF) @@ -272,17 +274,17 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); break; case 2: - dprintk(1, "switching SAA7113 to Video AV CVBS Input.\n"); + dprintk(1, "switching SAA7113 to Video AV CVBS Input\n"); if (i2c_writereg(av7110, 0x48, 0x02, 0xd2) != 1) dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); break; case 3: - dprintk(1, "switching SAA7113 to Video AV Y/C Input.\n"); + dprintk(1, "switching SAA7113 to Video AV Y/C Input\n"); if (i2c_writereg(av7110, 0x48, 0x02, 0xd9) != 1) dprintk(1, "saa7113 write failed @ card %d", av7110->dvb_adapter.num); break; default: - dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input.\n"); + dprintk(1, "switching SAA7113 to Input: AV7110: SAA7113: invalid input\n"); } } else { adswitch = 0; @@ -299,7 +301,7 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh) if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { if (ves1820_writereg(dev, 0x09, 0x0f, 0x20)) - dprintk(1, "setting band in demodulator failed.\n"); + dprintk(1, "setting band in demodulator failed\n"); } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) @@ -413,7 +415,7 @@ static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency); + dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x\n", f->frequency); if (!av7110->analog_tuner_flags || av7110->current_input != 1) return -EINVAL; @@ -429,7 +431,7 @@ static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct av7110 *av7110 = (struct av7110 *)dev->ext_priv; - dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency); + dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x\n", f->frequency); if (!av7110->analog_tuner_flags || av7110->current_input != 1) return -EINVAL; @@ -689,12 +691,12 @@ int av7110_init_analog_module(struct av7110 *av7110) if (i2c_writereg(av7110, 0x80, 0x0, 0x80) == 1 && i2c_writereg(av7110, 0x80, 0x0, 0) == 1) { - printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", + pr_info("DVB-C analog module @ card %d detected, initializing MSP3400\n", av7110->dvb_adapter.num); av7110->adac_type = DVB_ADAC_MSP34x0; } else if (i2c_writereg(av7110, 0x84, 0x0, 0x80) == 1 && i2c_writereg(av7110, 0x84, 0x0, 0) == 1) { - printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3415\n", + pr_info("DVB-C analog module @ card %d detected, initializing MSP3415\n", av7110->dvb_adapter.num); av7110->adac_type = DVB_ADAC_MSP34x5; } else @@ -715,7 +717,7 @@ int av7110_init_analog_module(struct av7110 *av7110) msp_writereg(av7110, MSP_WR_DSP, 0x000d, 0x1900); // prescale SCART if (i2c_writereg(av7110, 0x48, 0x01, 0x00)!=1) { - INFO(("saa7113 not accessible.\n")); + pr_info("saa7113 not accessible\n"); } else { u8 *i = saa7113_init_regs; @@ -733,7 +735,7 @@ int av7110_init_analog_module(struct av7110 *av7110) /* setup for DVB by default */ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) { if (ves1820_writereg(av7110->dev, 0x09, 0x0f, 0x20)) - dprintk(1, "setting band in demodulator failed.\n"); + dprintk(1, "setting band in demodulator failed\n"); } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) { saa7146_setgpio(av7110->dev, 1, SAA7146_GPIO_OUTLO); // TDA9819 pin9(STD) saa7146_setgpio(av7110->dev, 3, SAA7146_GPIO_OUTLO); // TDA9819 pin30(VIF) @@ -797,7 +799,7 @@ int av7110_init_v4l(struct av7110 *av7110) ret = saa7146_vv_init(dev, vv_data); if (ret) { - ERR(("cannot init capture device. skipping.\n")); + ERR("cannot init capture device. skipping\n"); return -ENODEV; } vv_data->ops.vidioc_enum_input = vidioc_enum_input; @@ -814,12 +816,12 @@ int av7110_init_v4l(struct av7110 *av7110) vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out; if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture device. skipping.\n")); + ERR("cannot register capture device. skipping\n"); saa7146_vv_release(dev); return -ENODEV; } if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) - ERR(("cannot register vbi v4l2 device. skipping.\n")); + ERR("cannot register vbi v4l2 device. skipping\n"); return 0; } diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index e957d76..78d32f7 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c @@ -33,6 +33,8 @@ * the project's page is at http://www.linuxtv.org/ */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "budget.h" #include "stv0299.h" #include "stb0899_drv.h" @@ -149,7 +151,7 @@ static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int ad result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1); if (result == -ETIMEDOUT) { ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 1\n"); + pr_info("cam ejected 1\n"); } return result; } @@ -168,7 +170,7 @@ static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int a result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1); if (result == -ETIMEDOUT) { ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 2\n"); + pr_info("cam ejected 2\n"); } return result; } @@ -187,7 +189,7 @@ static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addre result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0); if (result == -ETIMEDOUT) { ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 3\n"); + pr_info("cam ejected 3\n"); return -ETIMEDOUT; } return result; @@ -207,7 +209,7 @@ static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 addr result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0); if (result == -ETIMEDOUT) { ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 5\n"); + pr_info("cam ejected 5\n"); } return result; } @@ -289,7 +291,7 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open if (saa7146_read(saa, PSR) & MASK_06) { if (budget_av->slot_status == SLOTSTATUS_NONE) { budget_av->slot_status = SLOTSTATUS_PRESENT; - printk(KERN_INFO "budget-av: cam inserted A\n"); + pr_info("cam inserted A\n"); } } saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); @@ -306,11 +308,11 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1); if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) { budget_av->slot_status = SLOTSTATUS_PRESENT; - printk(KERN_INFO "budget-av: cam inserted B\n"); + pr_info("cam inserted B\n"); } else if (result < 0) { if (budget_av->slot_status != SLOTSTATUS_NONE) { ciintf_slot_shutdown(ca, slot); - printk(KERN_INFO "budget-av: cam ejected 5\n"); + pr_info("cam ejected 5\n"); return 0; } } @@ -365,11 +367,11 @@ static int ciintf_init(struct budget_av *budget_av) if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, &budget_av->ca, 0, 1)) != 0) { - printk(KERN_ERR "budget-av: ci initialisation failed.\n"); + pr_err("ci initialisation failed\n"); goto error; } - printk(KERN_INFO "budget-av: ci interface initialised.\n"); + pr_info("ci interface initialised\n"); return 0; error: @@ -896,7 +898,6 @@ static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = { { STB0899_DISRX_ST0 , 0x04 }, { STB0899_DISRX_ST1 , 0x00 }, { STB0899_DISPARITY , 0x00 }, - { STB0899_DISFIFO , 0x00 }, { STB0899_DISSTATUS , 0x20 }, { STB0899_DISF22 , 0x8c }, { STB0899_DISF22RX , 0x9a }, @@ -1197,6 +1198,7 @@ static u8 read_pwm(struct budget_av *budget_av) #define SUBID_DVBC_KNC1 0x0020 #define SUBID_DVBC_KNC1_PLUS 0x0021 #define SUBID_DVBC_KNC1_MK3 0x0022 +#define SUBID_DVBC_KNC1_TDA10024 0x0028 #define SUBID_DVBC_KNC1_PLUS_MK3 0x0023 #define SUBID_DVBC_CINERGY1200 0x1156 #define SUBID_DVBC_CINERGY1200_MK3 0x1176 @@ -1316,6 +1318,7 @@ static void frontend_init(struct budget_av *budget_av) case SUBID_DVBC_EASYWATCH_MK3: case SUBID_DVBC_CINERGY1200_MK3: case SUBID_DVBC_KNC1_MK3: + case SUBID_DVBC_KNC1_TDA10024: case SUBID_DVBC_KNC1_PLUS_MK3: budget_av->reinitialise_demod = 1; budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; @@ -1343,8 +1346,7 @@ static void frontend_init(struct budget_av *budget_av) } if (fe == NULL) { - printk(KERN_ERR "budget-av: A frontend driver was not found " - "for device [%04x:%04x] subsystem [%04x:%04x]\n", + pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n", saa->pci->vendor, saa->pci->device, saa->pci->subsystem_vendor, @@ -1356,7 +1358,7 @@ static void frontend_init(struct budget_av *budget_av) if (dvb_register_frontend(&budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) { - printk(KERN_ERR "budget-av: Frontend registration failed!\n"); + pr_err("Frontend registration failed!\n"); dvb_frontend_detach(budget_av->budget.dvb_frontend); budget_av->budget.dvb_frontend = NULL; } @@ -1414,7 +1416,7 @@ static struct v4l2_input knc1_inputs[KNC1_INPUTS] = { static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) { - dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index); + dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index); if (i->index >= KNC1_INPUTS) return -EINVAL; memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input)); @@ -1428,7 +1430,7 @@ static int vidioc_g_input(struct file *file, void *fh, unsigned int *i) *i = budget_av->cur_input; - dprintk(1, "VIDIOC_G_INPUT %d.\n", *i); + dprintk(1, "VIDIOC_G_INPUT %d\n", *i); return 0; } @@ -1437,7 +1439,7 @@ static int vidioc_s_input(struct file *file, void *fh, unsigned int input) struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; struct budget_av *budget_av = (struct budget_av *)dev->ext_priv; - dprintk(1, "VIDIOC_S_INPUT %d.\n", input); + dprintk(1, "VIDIOC_S_INPUT %d\n", input); return saa7113_setinput(budget_av, input); } @@ -1476,7 +1478,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio if (0 != saa7146_vv_init(dev, &vv_data)) { /* fixme: proper cleanup here */ - ERR(("cannot init vv subsystem.\n")); + ERR("cannot init vv subsystem\n"); return err; } vv_data.ops.vidioc_enum_input = vidioc_enum_input; @@ -1485,7 +1487,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) { /* fixme: proper cleanup here */ - ERR(("cannot register capture v4l2 device.\n")); + ERR("cannot register capture v4l2 device\n"); saa7146_vv_release(dev); return err; } @@ -1502,13 +1504,12 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio mac = budget_av->budget.dvb_adapter.proposed_mac; if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { - printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n", + pr_err("KNC1-%d: Could not read MAC from KNC1 card\n", budget_av->budget.dvb_adapter.num); memset(mac, 0, 6); } else { - printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", - budget_av->budget.dvb_adapter.num, - mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + pr_info("KNC1-%d: MAC addr = %pM\n", + budget_av->budget.dvb_adapter.num, mac); } budget_av->budget.dvb_adapter.priv = budget_av; @@ -1558,6 +1559,7 @@ MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP); MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3); +MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024); MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3); MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); @@ -1587,6 +1589,7 @@ static struct pci_device_id pci_tbl[] = { MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022), + MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028), MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023), MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 926f299..ca02e97 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c @@ -1053,7 +1053,6 @@ static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = { { STB0899_DISRX_ST0 , 0x04 }, { STB0899_DISRX_ST1 , 0x00 }, { STB0899_DISPARITY , 0x00 }, - { STB0899_DISFIFO , 0x00 }, { STB0899_DISSTATUS , 0x20 }, { STB0899_DISF22 , 0x8c }, { STB0899_DISF22RX , 0x9a }, diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 37666d4..37d02fe 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c @@ -110,6 +110,7 @@ static int start_ts_capture(struct budget *budget) break; case BUDGET_CIN1200C_MK3: case BUDGET_KNC1C_MK3: + case BUDGET_KNC1C_TDA10024: case BUDGET_KNC1CP_MK3: if (budget->video_port == BUDGET_VIDEO_PORTA) { saa7146_write(dev, DD1_INIT, 0x06000200); @@ -434,6 +435,7 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, case BUDGET_KNC1CP: case BUDGET_CIN1200C: case BUDGET_KNC1C_MK3: + case BUDGET_KNC1C_TDA10024: case BUDGET_KNC1CP_MK3: case BUDGET_CIN1200C_MK3: budget->buffer_width = TS_WIDTH_DVBC; diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index 3ad0c67..3d8a806 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h @@ -104,6 +104,7 @@ static struct saa7146_pci_extension_data x_var = { \ #define BUDGET_KNC1C_MK3 16 #define BUDGET_KNC1CP_MK3 17 #define BUDGET_KNC1S2 18 +#define BUDGET_KNC1C_TDA10024 19 #define BUDGET_VIDEO_PORTA 0 #define BUDGET_VIDEO_PORTB 1 diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.c b/drivers/media/dvb/ttpci/ttpci-eeprom.c index 7dd54b3..32d4315 100644 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.c +++ b/drivers/media/dvb/ttpci/ttpci-eeprom.c @@ -85,6 +85,35 @@ static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC) return 0; } +int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC) +{ + u8 xor[20] = { 0x72, 0x23, 0x68, 0x19, 0x5c, 0xa8, 0x71, 0x2c, + 0x54, 0xd3, 0x7b, 0xf1, 0x9E, 0x23, 0x16, 0xf6, + 0x1d, 0x36, 0x64, 0x78}; + u8 data[20]; + int i; + + memcpy(data, encodedMAC, 20); + + for (i = 0; i < 20; i++) + data[i] ^= xor[i]; + for (i = 0; i < 10; i++) + data[i] = ((data[2 * i + 1] << 8) | data[2 * i]) + >> ((data[2 * i + 1] >> 6) & 3); + + if (check_mac_tt(data)) + return -ENODEV; + + decodedMAC[0] = data[2]; + decodedMAC[1] = data[1]; + decodedMAC[2] = data[0]; + decodedMAC[3] = data[6]; + decodedMAC[4] = data[5]; + decodedMAC[5] = data[4]; + return 0; +} +EXPORT_SYMBOL(ttpci_eeprom_decode_mac); + static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC) { int ret; diff --git a/drivers/media/dvb/ttpci/ttpci-eeprom.h b/drivers/media/dvb/ttpci/ttpci-eeprom.h index e2dc6cf..dcc33d5 100644 --- a/drivers/media/dvb/ttpci/ttpci-eeprom.h +++ b/drivers/media/dvb/ttpci/ttpci-eeprom.h @@ -28,6 +28,7 @@ #include <linux/types.h> #include <linux/i2c.h> +extern int ttpci_eeprom_decode_mac(u8 *decodedMAC, u8 *encodedMAC); extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac); #endif diff --git a/drivers/media/dvb/ttusb-budget/Makefile b/drivers/media/dvb/ttusb-budget/Makefile index fbe2b95..8d6c4ac 100644 --- a/drivers/media/dvb/ttusb-budget/Makefile +++ b/drivers/media/dvb/ttusb-budget/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_DVB_TTUSB_BUDGET) += dvb-ttusb-budget.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends +ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends diff --git a/drivers/media/dvb/ttusb-dec/Makefile b/drivers/media/dvb/ttusb-dec/Makefile index 2d70a82..ed28b53 100644 --- a/drivers/media/dvb/ttusb-dec/Makefile +++ b/drivers/media/dvb/ttusb-dec/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_DVB_TTUSB_DEC) += ttusb_dec.o ttusbdecfe.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ diff --git a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c index 21260aa..852870b 100644 --- a/drivers/media/dvb/ttusb-dec/ttusbdecfe.c +++ b/drivers/media/dvb/ttusb-dec/ttusbdecfe.c @@ -154,6 +154,9 @@ static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struc 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + if (cmd->msg_len > sizeof(b) - 4) + return -EINVAL; + memcpy(&b[4], cmd->msg, cmd->msg_len); state->config->send_command(fe, 0x72, |